希望您知道,您可以在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);
代替一些丑陋的匿名内部类,有没有办法让它变得更好?
发布于 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;
}
}
发布于 2015-02-27 18:52:57
要完成Marko Topolnik关于Timer
的回答,您只需使用lambda调用schedule
方法。
schedule(() -> {
System.out.println("Task #1 is running");
}, 500);
发布于 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));
这使您可以更好地控制计时器,并且您拥有一个静态实用程序类。理想情况下,给它起一个不会与其他公共线程类冲突的名称,而不是任务、作业、计时器。
https://stackoverflow.com/questions/22378422
复制相似问题