当前位置: 首页 > 知识库问答 >
问题:

如何在lambdas中使用TimerTask?

公孙盛
2023-03-14

如您所知,您可以在Java 8中使用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);

除了一些丑陋的匿名内部类,还有什么方法可以让它变得更好吗?

共有3个答案

和嘉澍
2023-03-14

虽然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));

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

许永年
2023-03-14

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

schedule(() -> {
    System.out.println("Task #1 is running");
}, 500);
闻人望
2023-03-14

首先注意到Timer实际上是一个过时的API,但考虑到您的问题,您可以在它周围编写一个小包装器,它将调整调度方法以接受Runnable,并在内部将该Runnable转换为TimerTask。然后您将拥有接受lambda的时间表方法。

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;
  }
}
 类似资料:
  • 问题内容: public void test(){ String x; List list=Arrays.asList(“a”,”b”,”c”,”d”); 1,像上面的代码一样,我想在foreach块旁边设置一个变量的值,行得通吗? 2.为什么呢? 3,而foreach迭代器是有序的还是无序的? 4,我认为lamdas foreach块对于迭代器来说很酷而且很简单,但这确实是一件很复杂的事情,而不

  • 我正在做一个程序的一部分(关于语音识别和遥控车),其中代码重复多次。出于好奇,我想将其转换为类似于(原谅;我不知道表达式的类型),然后以类似以下方式调用它:、和或类似于、和。 在Java中使用简单的lambda函数的正确语法是什么?(我应该把它的类型写下来,而不是说?) 如果您好奇的话,下面是代码块:

  • 我有一个比较器,它检查字符串是否为空,并返回-1。如果它们不是null,则进行比较。我想用lambda函数实现这个。 以下是代码: 我知道如何使用lambdas返回一个简单的比较器。我对如何实现上述代码感到困惑。

  • 问题内容: 例如,在匿名内部类的情况下,传递(匿名)对象引用并执行该对象的方法。 Lambda是将在需要时执行的代码块。 遇到lambda时,JVM中会发生什么?JVM在哪里存储与lambda相关的代码块(堆:年轻,老旧或永久生成)? 我尝试搜索,但得到了使用lambda的语法,但无法理解JVM内部发生的情况,因为在JAVA中,一切都是基于对象的。 因此,在OOP中,lambda如何工作? lam

  • Lambda表达式是一种很简单的方法,去定义一个匿名函数。Lambda是非常有用的,因为它们避免我们去写一些包含了某些函数的抽象类或者接口,然后在类中去实现它们。在Kotlin,我们把一个函数作为另一个函数的参数。

  • 对于如何使用Java8Lambdas将对象添加到另一个列表中,我有一个疑问。 让我解释一下: 我有以下对象: 类对象: 学生对象: 主客体: 我想这样做,但使用java 8 lambda: 总的来说:-我想在我的课程列表中找到学生的名字 一旦我找到了学生姓名,我想在科目列表中添加一个新的科目信息