Java 如何将 TimerTask 与 lambdas 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22378422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use TimerTask with lambdas?
提问by skiwi
As you hopefully know you can use lambdas in Java 8, for example to replace anonymous methods.
正如您希望知道的那样,您可以在 Java 8 中使用 lambda,例如替换匿名方法。
An example can be seen here of Java 7 vs Java 8:
可以在此处看到 Java 7 与 Java 8 的示例:
Runnable runnable = new Runnable() {
@Override
public void run() {
checkDirectory();
}
};
Can be expressed as both the following ways in Java 8:
在 Java 8 中可以表示为以下两种方式:
Runnable runnable = () -> checkDirectory();
or
或者
Runnable runnable = this::checkDirectory;
This is because Runnable
is a functional interface, having only one (abstract) public non-default method.
这是因为Runnable
是一个函数式接口,只有一个(抽象的)公共非默认方法。
However... For TimerTask
we have the following:
但是......因为TimerTask
我们有以下内容:
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
checkDirectory();
}
};
Looks familiar, right?
Using a lambda expression does not work though, because TimerTask
is an abstract class, even though it has only one abstract public non-default method, it is not an interface and hence no functional interface either.
It is also not refactored into an interface with default implementations, because it carries state, so that cannot be done then.
看起来很熟悉对不对?
但是使用 lambda 表达式不起作用,因为它TimerTask
是一个抽象类,即使它只有一个抽象的公共非默认方法,它也不是一个接口,因此也没有功能接口。
它也没有被重构为具有默认实现的接口,因为它携带状态,因此无法完成。
So my question: Is there any way to use lambdas when constructing the TimerTask
?
所以我的问题是:在构造TimerTask
.
What I wanted is the following:
我想要的是以下内容:
Timer timer = new Timer();
timer.schedule(this::checkDirectory, 0, 1 * 1000);
Instead of some ugly anonymous inner class, is there any way to make it nicer?
除了一些丑陋的匿名内部类,有没有办法让它更好?
采纳答案by Marko Topolnik
Noting first that Timer
is effectively an antiquated API, but entertaining your question nevertheless, you could write a small wrapper around it which would adapt the schedule
method to accept a Runnable
, and on the inside you'd turn that Runnable
into a TimerTask
. Then you would have your schedule
method which would accept a lambda.
首先请注意,这Timer
实际上是一个过时的 API,但尽管如此,还是可以娱乐您的问题,您可以围绕它编写一个小包装器,使该schedule
方法能够接受 a 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;
}
}
回答by Fran?ois SAMIN
To complete Marko Topolnik's answer about Timer
, you just have to call schedule
method with a lambda.
要完成 Marko Topolnik 关于 的回答Timer
,您只需schedule
使用 lambda调用方法。
schedule(() -> {
System.out.println("Task #1 is running");
}, 500);
回答by lapsus63
You can also create a Timer easily with lambdas from the Swing API if you want (but not with TimerTask) :
如果需要,您还可以使用 Swing API 中的 lambdas 轻松创建计时器(但不能使用 TimerTask):
new javax.swing.Timer(1000, (ae) -> this::checkDirectory).start();
new javax.swing.Timer(1000, (ae) -> this::checkDirectory).start();
回答by Kalec
While Marko's answer is perfectly correct, I prefer my implementation:
虽然 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));
This gives you more control over the timer, and you have a static utility class. Idealy give it a name that won't conflict with other common thread class, so not Task, Job, Timer.
这使您可以更好地控制计时器,并且您有一个静态实用程序类。理想情况下,给它一个不会与其他公共线程类冲突的名称,所以不要给它 Task、Job、Timer。