2014-03-13 39 views
19

正如您所希望的那樣,您可以使用Java 8中的lambdas來替換匿名方法。如何將lambda使用TimerTask?

的例子可以在這裏的Java 7中看到的和Java 8:

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

可表現爲無論是在Java的8以下幾種方式:

Runnable runnable =() -> checkDirectory(); 

Runnable runnable = this::checkDirectory; 

這是因爲Runnable是一個功能接口,只有一個(抽象)公共非默認我的ThOD。

但是......對於TimerTask,我們有以下幾點:

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

看起來很熟悉吧?
雖然使用lambda表達式不起作用,因爲TimerTask是一個抽象類,儘管它只有一個抽象的公共非默認方法,但它不是一個接口,因此也沒有功能接口。
它也不會被重構到默認實現的接口中,因爲它帶有狀態,所以當時無法完成。

所以我的問題:有什麼辦法可以在構建TimerTask時使用lambdas?

我想要的東西是這樣的:

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

相反一些醜陋的匿名內部類的,有沒有什麼辦法讓它更好?

+7

由於您使用的現代功能,爲什麼不走一路並使用'ScheduledExecutorService'而不是'TimerTask'? ;) – fge

+0

@fge那麼,我不知道它的存在,直到現在......現在我想起來了,Java沒有他們的API提到有一個更新的類似功能可用,當舊功能尚未*推薦*? – skiwi

+0

對於Timer,Josh Bloch的Effective Java 2nd Edition建議。不過,它並不是JDK API的官方位置。 –

回答

10

首先注意到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; 
    } 
} 
+9

從技術上講,您的答案是正確的,但是我會親自使用'ScheduledExecutorService'而不是'TimerTask'。 – skiwi

+1

和一個很好的選擇:) –

+1

什麼是當前的API呢? – krivar

0

要完成馬爾科Topolnik的回答Timer,你只需要調用schedule方法是lambda。

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

'Runnable'是一個接口,你可以用lambda實現它。所以你可以用lambda調用'schedule'方法。這裏是一個工作要點https://gist.github.com/fsamin/ec5aa79bc23965eca277 –

+1

誤解的答案;當然,你完全正確。 – gerardw

-1

你也可以很容易地創建一個定時器,從Swing API lambda表達式,如果你想要的(但不是TimerTask的):

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