Come verificare se l'elemento esiste utilizzando un'espressione lambda?


118

Nello specifico, ho TabPane e vorrei sapere se contiene un elemento con un ID specifico.

Quindi, vorrei farlo con l'espressione lambda in Java:

boolean idExists = false;
String idToCheck = "someId";

for (Tab t : tabPane.getTabs()){
    if(t.getId().equals(idToCheck)) {
        idExists = true;
    }
}

Risposte:


273

Prova a utilizzare anyMatchLambda Expression. È un approccio molto migliore.

 boolean idExists = tabPane.getTabs().stream()
            .anyMatch(t -> t.getId().equals(idToCheck));

11
Vale anche la pena notare: se vuoi negare il segno di spunta usa noneMatchinvece di anyMatch.
Blacklight

La chiamata richiede il livello API 24
FabioLux

50

Sebbene la risposta accettata sia corretta, aggiungerò una versione più elegante (a mio parere):

boolean idExists = tabPane.getTabs().stream()
    .map(Tab::getId)
    .anyMatch(idToCheck::equals);

Non trascurare l'uso di Stream # map () che consente di appiattire la struttura dei dati prima di applicare il Predicate.


3
cosa c'è di meglio qui? Vedo solo un'altra operazione. Mi dispiace di essere nuovo a questa cosa del lamba.
TecHunter

2
@TecHunter è più esplicito. Immagina di leggere questo codice la prima volta o di nuovo dopo un po '. Ci sono diversi vantaggi: in primo luogo, dimostriamo immediatamente che non siamo effettivamente interessati alla scheda, ma una mappatura di essa. In secondo luogo, utilizzando i riferimenti al metodo (che è possibile solo perché suddividiamo il lambda iniziale in due passaggi) dimostriamo che non ci sono sorprese nascoste nel codice. Terzo, utilizzando i riferimenti al metodo, non creiamo un nuovo predicato, ma in realtà ci limitiamo a riutilizzarlo equals. Sebbene, scontato, l'esempio qui sia molto semplice, ma spero che tu abbia capito cosa intendo.
Malte Hartwig

@MalteHartwig grazie! si ottengo i tuoi 3 punti ma stavo chiedendo l'appiattimento con map, fa un altro passaggio di elaborazione no? Proverò a confrontare i 2 metodi :)
TecHunter

1
@MalteHartwig testato in un ArrayList 10kk con un semplice oggetto cercando di trovare l'ultimo elemento. dà una differenza di 2 ms 131 ms contro 133 ms per il tuo. su un array da 1kk elenca il tuo se più veloce di 2ms (da 55ms a 53ms). Quindi possiamo dire che il tuo è migliore :)
TecHunter

2
I getter di @TecHunter sono super economici. Preferisci sempre la chiarezza del codice rispetto al risparmio di 2 millisecondi extra (anche se, dubito che i risultati siano accurati, potrebbe fluttuare ad ogni esecuzione). Inoltre, ricorda che le operazioni intermedie sui flussi (come map) sono pigre per natura. Ciò significa che il getIdmetodo non viene applicato a ogni elemento della raccolta. Viene valutato pigramente finché non anyMatchrestituisce true .
jFrenetic

3

Le risposte precedenti richiedono di eseguire il malloc di un nuovo oggetto stream.

public <T>
boolean containsByLambda(Collection<? extends T> c, Predicate<? super T> p) {

    for (final T z : c) {
        if (p.test(z)) {
            return true;
        }
    }
    return false;
}

public boolean containsTabById(TabPane tabPane, String id) {
    return containsByLambda(tabPane.getTabs(), z -> z.getId().equals(id));
}
...
if (containsTabById(tabPane, idToCheck))) {
   ...
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.