如何将TimerTask与lambdas一起使用?

正如您所知,您可以在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是一个function接口,只有一个(抽象)公共非默认方法。

但是……对于TimerTask我们有以下内容:

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

看起来很熟悉吧?
但是使用lambda表达式不起作用,因为TimerTask是一个抽象类,即使它只有一个抽象的公共非默认方法,它也不是一个接口,因此也没有function接口。
它也没有重构为具有默认实现的接口,因为它带有状态,因此无法完成。

所以我的问题 :在构造TimerTask时有没有办法使用lambdas?

我想要的是以下内容:

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

而不是一些丑陋的匿名内部类,有没有办法让它更好?

首先注意到Timer实际上是一个过时的API,但是尽管如此,你可以在它周围编写一个小包装器来调整schedule方法以接受Runnable ,在内部你可以将Runnable变成TimerTask 。 然后你会有你的schedule方法接受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; } } 

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

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

如果需要,您也可以使用Swing API中的lambdas轻松创建Timer(但不能使用TimerTask):

new javax.swing.Timer(1000, (ae) -> this::checkDirectory).start();