首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将TimerTask与lambda一起使用?

如何将TimerTask与lambda一起使用?
EN

Stack Overflow用户
提问于 2014-03-13 20:18:06
回答 5查看 18.5K关注 0票数 25

希望您知道,您可以在Java8中使用lambdas,例如,用它来替换匿名方法。

下面是Java 7与Java 8的对比示例:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        checkDirectory();
    }
};

在Java 8中,可以用以下两种方式来表示:

Runnable runnable = () -> checkDirectory();

Runnable runnable = this::checkDirectory;

这是因为Runnable是一个函数式接口,只有一个(抽象的)公共非默认方法。

然而..。对于TimerTask,我们有以下内容:

TimerTask timerTask = new TimerTask() {
    @Override
    public void run() {
        checkDirectory();
    }
};

看起来很眼熟,对吧?

使用lambda表达式是行不通的,因为TimerTask是一个抽象类,即使它只有一个抽象的公共非默认方法,它也不是一个接口,因此也没有函数接口。

它也没有被重构到默认实现的接口中,因为它携带状态,所以无法做到这一点。

那么我的问题:在构造TimerTask时,有没有办法使用lambda?

我想要的是:

Timer timer = new Timer();
timer.schedule(this::checkDirectory, 0, 1 * 1000);

代替一些丑陋的匿名内部类,有没有办法让它变得更好?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-03-13 20:22:19

首先要注意的是,Timer实际上是一个过时的应用程序接口,但是考虑到您的问题,您可以在它周围编写一个小包装器,使schedule方法适应接受Runnable,并在内部将该Runnable转换为TimerTask。然后,您将拥有接受lambda的schedule方法。

public class MyTimer {
  private final Timer t = new Timer();

  public TimerTask schedule(final Runnable r, long delay) {
     final TimerTask task = new TimerTask() { public void run() { r.run(); }};
     t.schedule(task, delay);
     return task;
  }
}
票数 14
EN

Stack Overflow用户

发布于 2015-02-27 18:52:57

要完成Marko Topolnik关于Timer的回答,您只需使用lambda调用schedule方法。

schedule(() -> {
    System.out.println("Task #1 is running");
}, 500);
票数 1
EN

Stack Overflow用户

发布于 2019-07-03 19:53:13

虽然Marko的答案是完全正确的,但我更喜欢我的实现:

public class FunctionalTimerTask extends TimerTask {

    Runnable task;

    public FunctionalTimerTask(Runnable task) {
        this.task = task;
    }

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

 public static class Task {
    public static TimerTask set(Runnable run) {
        return new FunctionalTimerTask(() -> System.err.println("task"));
    }
}

 Timer timer = new Timer(false);
 timer.schedule(Task.set(() -> doStuff()), TimeUnit.SECONDS.toMillis(1));

这使您可以更好地控制计时器,并且您拥有一个静态实用程序类。理想情况下,给它起一个不会与其他公共线程类冲突的名称,而不是任务、作业、计时器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22378422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档