我想在地图上执行延迟操作,所以我使用Timer
,我传递的是TimerTask
,延迟时间是毫秒:
timer.schedule(new TimerTask() {
public void run() {
tournaments.remove(id);
}
}, delay);
这是一种类似原始缓存的功能,我在刚刚创建的新资源上设置了到期时间。
我以为我可以使用lambdas做到这一点,如下所示:
times.schedule(() -> tournaments.remove(id), delay);
但是编译器说这不可能。为什么?我究竟做错了什么?我可以使用lambdas来实现更简洁的代码,或者在这里根本不可能,我应该坚持使用匿名类吗?
答案 0 :(得分:10)
为了使用lambda表达式,您需要一个必须是SAM类型的目标类型,即功能接口。由于TimerTask
是一个抽象类,所以你不能在这里使用lambdas
使用lambda表达式可以做的是编写一个实用函数,将代码包装成TimerTask
,如:
private static TimerTask wrap(Runnable r) {
return new TimerTask() {
@Override
public void run() {
r.run();
}
};
}
然后你可以使用你的lambda:
times.schedule(wrap(() -> tournaments.remove(id)), delay);
答案 1 :(得分:9)
TimerTask
不是SAM(单一抽象方法)类型 - 现在,这听起来很矛盾,因为TimerTask上只有一个抽象方法!但是因为抽象父类实现了cancel
和scheduledExecutionTime
,即使它们不是抽象的,编译器也不能采用你的lambda并创建一个匿名子类型TimerTask
。
可以做的是具有单个抽象方法和一个或多个默认方法的接口的lambdas,但遗憾的是TimerTask是一个较旧的类,并且不使用默认的方法功能Java 8。