java lambda abstract-class timertask java-8

java - ¿Cómo usar TimerTask con lambdas?



abstract-class java-8 (3)

Observando primero que Timer es efectivamente una API anticuada, pero sin embargo, entreteniendo su pregunta, podría escribir un pequeño envoltorio a su alrededor que adaptaría el método de schedule para aceptar un Runnable , y en el interior convertiría ese Runnable en una TimerTask . Entonces tendrías tu método de schedule que aceptaría un 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; } }

Como es de esperar, puede utilizar lambdas en Java 8, por ejemplo, para reemplazar métodos anónimos.

Un ejemplo se puede ver aquí de Java 7 vs Java 8:

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

Se puede expresar de la siguiente manera en Java 8:

Runnable runnable = () -> checkDirectory();

o

Runnable runnable = this::checkDirectory;

Esto se debe a que Runnable es una interfaz funcional que solo tiene un método público no predeterminado (abstracto).

Sin embargo ... Para TimerTask tenemos lo siguiente:

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

Parece familiar, ¿verdad?
Sin embargo, el uso de una expresión lambda no funciona, porque TimerTask es una clase abstracta, a pesar de que solo tiene un método público abstracto no predeterminado, no es una interfaz y, por lo tanto, tampoco es una interfaz funcional.
Tampoco se ha refaccionado en una interfaz con implementaciones predeterminadas, porque lleva el estado, por lo que no se puede hacer en ese momento.

Entonces, mi pregunta : ¿Hay alguna forma de usar lambdas cuando se construye TimerTask ?

Lo que quería era lo siguiente:

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

En lugar de una clase interna anónima y fea, ¿hay alguna manera de hacerlo mejor?


Para completar la respuesta de Marko Topolnik sobre el Timer , solo tiene que llamar al método de schedule con un lambda.

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


También puede crear un temporizador fácilmente con lambdas desde la API de Swing si lo desea (pero no con TimerTask):

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