问题
I want to perform a delayed operation on a map, so I am using Timer
, to which I am passing a TimerTask
and a delay in milliseconds:
timer.schedule(new TimerTask() {
public void run() {
tournaments.remove(id);
}
}, delay);
This is some sort of primitive cache-like functionality where I set an expiration time on a new resource that was just created.
I thought I could do that using lambdas, just like follows:
times.schedule(() -> tournaments.remove(id), delay);
But the compiler says this cannot be done. Why? What am I doing wrong? Could I use lambdas to achieve more concise code or it's simply not possible here and I should stick to an anonymous class?
回答1:
TimerTask
is not a SAM (single abstract method) type -- now, that sounds contradictory, because there is only one abstract method on TimerTask! But because the abstract parent class implements cancel
and scheduledExecutionTime
, even though they're not abstract, the compiler can't go so far as to take your lambda and create an anonymous subtype of TimerTask
.
What can be done is lambdas for interfaces that have a single abstract method and one or more default methods, but sadly TimerTask is an older class and doesn't use the default method capabilities of Java 8.
回答2:
In order to use lambda expression you need a target type which has to be a SAM type, i.e. functional interface. Since TimerTask
is an abstract class you can't use lambdas here.
What you can do, to use lambda expressions, is to write an utility function which wraps your code into a TimerTask
like:
private static TimerTask wrap(Runnable r) {
return new TimerTask() {
@Override
public void run() {
r.run();
}
};
}
Then you can use your lambda:
times.schedule(wrap(() -> tournaments.remove(id)), delay);
来源:https://stackoverflow.com/questions/37970682/passing-lambda-to-a-timer-instead-of-timertask