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.