Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use TimerTask with lambdas?

Tags:

As you hopefully know you can use lambdas in Java 8, for example to replace anonymous methods.

An example can be seen here of Java 7 vs Java 8:

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

Can be expressed as both the following ways in 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.

However... For TimerTask we have the following:

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.

So my question: Is there any way to use lambdas when constructing the 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?

like image 584
skiwi Avatar asked Mar 13 '14 12:03

skiwi


People also ask

Why do I need a functional interface to work with lambdas?

You give an implementation to the void hans() method of the TestInterface . If you could assign a lambda expression to an interface having more than one abstract method (i.e. a non functional interface), the lambda expression could only implement one of the methods, leaving the other methods unimplemented.

Can lambda function have multiple methods?

Since a lambda function can only provide the implementation for 1 method it is mandatory for the functional interface to have ONLY one abstract method.

Are lambdas faster in Java?

I've seen a lot of questions here about Java lambdas performance, but most of them go like "Lambdas are slightly faster, but become slower when using closures" or "Warm-up vs execution times are different" or other such things.

Are lambdas more efficient?

Generally speaking, lambdas and streams provide a more concise and (once everyone is up to speed) more readable way of expressing this kind of algorithm.


2 Answers

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.

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;   } } 
like image 92
Marko Topolnik Avatar answered Oct 08 '22 13:10

Marko Topolnik


To complete Marko Topolnik's answer about Timer, you just have to call schedule method with a lambda.

schedule(() -> {     System.out.println("Task #1 is running"); }, 500); 
like image 24
François SAMIN Avatar answered Oct 08 '22 13:10

François SAMIN