java 将 lambda 传递给 Timer 而不是 TimerTask

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37970682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:59:18  来源:igfitidea点击:

Passing lambda to a Timer instead of TimerTask

javalambdajava-8

提问by dabadaba

I want to perform a delayed operation on a map, so I am using Timer, to which I am passing a TimerTaskand a delay in milliseconds:

我想在地图上执行延迟操作,所以我正在使用Timer, 我正在向它传递一个TimerTask和一个以毫秒为单位的延迟:

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:

我想我可以使用 lambdas 来做到这一点,就像下面这样:

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?

但是编译器说这是做不到的。为什么?我究竟做错了什么?我可以使用 lambdas 来实现更简洁的代码,还是在这里根本不可能,我应该坚持使用匿名类?

回答by Tom G

TimerTaskis 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 canceland 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.

TimerTask不是 SAM(单一抽象方法)类型——现在,这听起来很矛盾,因为 TimerTask 只有一个抽象方法!但是因为抽象父类实现了canceland scheduledExecutionTime,即使它们不是抽象的,编译器也不能采用你的 lambda 并创建一个匿名子类型TimerTask

What can be done is lambdas for interfaces that have a single abstract method and one or more defaultmethods, but sadly TimerTask is an older class and doesn't use the default method capabilities of Java 8.

可以做的是用于具有单个抽象方法和一个或多个默认方法的接口的 lambda ,但遗憾的是 TimerTask 是一个较旧的类,不使用 Java 8 的默认方法功能。

回答by Flown

In order to use lambda expression you need a target type which has to be a SAM type, i.e. functional interface. Since TimerTaskis 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 TimerTasklike:

为了使用 lambda 表达式,您需要一个目标类型,它必须是 SAM 类型,即功能接口。由于TimerTask是抽象类,因此您不能在此处使用 lambda。
要使用 lambda 表达式,您可以做的是编写一个实用程序函数,将您的代码包装成TimerTask如下形式:

private static TimerTask wrap(Runnable r) {
  return new TimerTask() {

    @Override
    public void run() {
      r.run();
    }
  };
}

Then you can use your lambda:

然后你可以使用你的 lambda:

times.schedule(wrap(() -> tournaments.remove(id)), delay);