2016-06-22 15 views
5

voglio eseguire un'operazione in ritardo su una mappa, in modo da sto usando Timer, a cui sto passando un e un ritardo TimerTask in millisecondi:Passando lambda ad un timer, invece di TimerTask

timer.schedule(new TimerTask() { 
    public void run() { 
     tournaments.remove(id); 
    } 
}, delay); 

Questo è una sorta di primitiva funzionalità simile alla cache in cui ho impostato un tempo di scadenza su una nuova risorsa appena creata.

ho pensato che avrei potuto farlo utilizzando lambda, proprio come segue:

times.schedule(() -> tournaments.remove(id), delay); 

Ma il compilatore dice che questo non può essere fatto. Perché? Che cosa sto facendo di sbagliato? Potrei usare lambda per ottenere un codice più conciso o semplicemente non è possibile qui e dovrei attenermi a una lezione anonima?

+3

Che cosa significa il compilatore dirvi? Inoltre, ti manca il secondo parametro 'delay' nel tuo esempio. – Zircon

+0

Si dice che "non è in grado di risolvere la pianificazione del metodo (, lunga)" * – dabadaba

+3

Si consiglia di utilizzare 'ScheduledExecutorService' in preferenza su' Timer'. –

risposta

4

TimerTask non è un tipo SAM (single abstract method) - ora, sembra contraddittorio, perché su TimerTask c'è solo un metodo astratto! Ma poiché la classe genitore astratta implementa cancel e scheduledExecutionTime, anche se non sono astratti, il compilatore non può arrivare al punto di prendere il lambda e creare un sottotipo anonimo di TimerTask.

Cosa si può fare è lambda per le interfacce che hanno un unico metodo astratto e uno o più predefinite metodi, ma purtroppo TimerTask è una classe più vecchia e non usufruisce delle funzionalità metodo di default di Java 8.

+1

Qualsiasi altra alternativa "moderna" per l'impostazione dei timer sarebbe conciso come quello che sto cercando di ottenere? – dabadaba

+2

Il termine che stai cercando è _interfaccia funzionale_. –

+0

@BrianGoetz ah, ha completamente superato la nomenclatura "SAM"? Immagino di non essere aggiornato. –

8

Per utilizzare l'espressione lambda è necessario un tipo di destinazione che deve essere un tipo SAM, ovvero un'interfaccia funzionale. Dal TimerTask è una classe astratta che non puoi usare lambda qui.
Cosa si può fare, per usare le espressioni lambda, è quello di scrivere una funzione di utilità che avvolge il codice in una TimerTask come:

private static TimerTask wrap(Runnable r) { 
    return new TimerTask() { 

    @Override 
    public void run() { 
     r.run(); 
    } 
    }; 
} 

Quindi è possibile utilizzare il lambda:

times.schedule(wrap(() -> tournaments.remove(id)), delay);