うまくいけば、Java 8でラムダを使用して、たとえば匿名メソッドを置き換えることができます。
Java 7 vs Java 8:
Runnable runnable = new Runnable() {
@Override
public void run() {
checkDirectory();
}
};
Java 8では、次の両方の方法で表すことができます。
Runnable runnable = () -> checkDirectory();
または
Runnable runnable = this::checkDirectory;
これは、Runnable
が機能的なインターフェイスであり、デフォルト以外のパブリックメソッド(抽象)が1つしかないためです。
ただし... TimerTask
の場合、次のようになります。
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
checkDirectory();
}
};
おなじみですね。
ただし、ラムダ式を使用しても機能しません。TimerTask
は抽象クラスであるため、デフォルト以外のパブリックメソッドが1つしかなくても、インターフェースではないため、機能インターフェースもありません。 。
また、状態を運ぶため、デフォルトの実装ではインターフェイスにリファクタリングされないため、その場合は実行できません。
だから私のquestion:TimerTask
を構築するときにラムダを使用する方法はありますか?
私が欲しかったのは以下です:
Timer timer = new Timer();
timer.schedule(this::checkDirectory, 0, 1 * 1000);
醜い匿名の内部クラスの代わりに、それをより良くする方法はありますか?
最初にTimer
は事実上時代遅れのAPIであることに注意してください。それでも質問を楽しませるには、schedule
メソッドを適合させてRunnable
を受け入れる小さなラッパーを書くことができます。内側では、そのRunnable
をTimerTask
に変換します。次に、ラムダを受け入れる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;
}
}
マルコの答えは完全に正しいですが、私は私の実装を好みます:
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));
これにより、タイマーをより詳細に制御でき、静的なユーティリティクラスが作成されます。他の一般的なスレッドクラスと競合しない名前を付けてください。タスク、ジョブ、タイマーではありません。
Marko TopolnikのTimer
に関する回答を完了するには、ラムダを使用してschedule
メソッドを呼び出すだけです。
schedule(() -> {
System.out.println("Task #1 is running");
}, 500);