1. Controllo
Penso che potresti già annoiarti di imparare come concatenare i flussi di dati. Vuoi finalmente fare qualcosa con i dati.
La Stream
classe ha tre metodi standard che non costruiscono flussi, ma invece controllano che tipo di dati sono in essi contenuti. Questi metodi sono: anyMatch()
, allMatch()
, e noneMatch()
.
boolean anyMatch(rule)
metodo
Questo metodo controlla se il flusso ha almeno un elemento che soddisfa la regola passata al metodo. Se esiste un tale elemento, il metodo restituisce true
, altrimenti false
.
Esempi
Codice | Nota |
---|---|
|
|
|
|
|
|
Nell'ultimo esempio, prima conserviamo solo gli elementi che sono minori di zero, quindi controlliamo il risultato per vedere se qualcuno degli elementi filtrati è maggiore di zero. Naturalmente, tali elementi non ci sono più.
metodo booleano allMatch(rule).
Questo metodo controlla se tutti gli elementi nel flusso corrispondono alla regola (nota anche come predicato). La regola viene passata come argomento al metodo:
Codice | Nota |
---|---|
|
(tutti gli elementi maggiori di zero) |
|
(ci sono elementi minori o uguali a zero?) |
|
(abbiamo mantenuto gli elementi che sono minori di zero) |
Nell'ultimo esempio, per prima cosa permettiamo solo agli elementi che sono minori di zero di passare attraverso il filtro, e poi controlliamo se tutti gli elementi conservati sono minori di zero. Il controllo dà esito positivo.
metodo booleano noneMatch(rule).
Il noneMatch()
metodo controlla se il flusso non ha elementi che corrispondono alla regola passata. È come l'opposto del anyMatch()
metodo.
Codice | Nota |
---|---|
|
|
|
|
|
|
2. Classi di utilità: Optional
classe
A volte è molto scomodo per i programmatori lavorare con null
i riferimenti. Ad esempio, supponi di confrontare due stringhe. Se entrambe le variabili non lo sono null
, puoi semplicemente chiamare s1.equals(s2)
e tutto funzionerà. Ma se s1
potrebbe essere null
, allora devi scrivere codice che gestisca questa situazione per evitare un errore NullPointerException
.
Ecco perché i programmatori hanno inventato la Optional<T>
classe di utilità. Il suo codice assomiglia più o meno a questo:
Codice | Nota |
---|---|
|
Controlla se il valore non è null Controlla se il valore è null Restituisce il valore memorizzato. Genera un'eccezione se il valore è null. Restituisce il valore non nullo archiviato. Oppure, se il valore archiviato è null , restituisce il valore passato come argomento del metodo Restituisce il valore non nullo archiviato o genera un'eccezione se il valore è nullo. |
Lo scopo di questa classe è semplicemente quello di memorizzare un oggetto T (un riferimento a un oggetto il cui tipo è T). Il riferimento all'oggetto all'interno di un Optional<T>
oggetto può essere null
.
Questa classe consente ai programmatori di scrivere un codice leggermente più carino. Confrontiamo:
Utilizzo facoltativo | Non usare Opzionale |
---|---|
|
|
Un Optional
oggetto può sempre essere confrontato con un altro Optional
oggetto utilizzando il equals
metodo, anche se memorizzano null
i riferimenti.
In parole povere, la Optional
classe ti consente di scrivere controlli "belli" null
e azioni "belli" nel caso in cui un Optional
oggetto memorizzi un null
valore.
3. Trovare elementi
Torniamo alla Stream
classe. La Stream
classe ha altri 4 metodi che ti consentono di cercare elementi in un flusso. Questi metodi sono findFirst()
, findAny()
, min()
e max()
.
Optional<T> findFirst()
metodo
Il findFirst()
metodo restituisce semplicemente il primo elemento nel flusso. Questo è tutto ciò che fa.
La cosa più interessante da notare qui è che il metodo non restituisce un T
oggetto, ma piuttosto un Optional<T>
oggetto wrapper. Ciò garantisce che il metodo non ritorni mai null
dopo aver fallito nel trovare un oggetto.
Esempio:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello
Per maggiore chiarezza, suddividiamo l'ultima riga in più righe:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello
L'ultimo get()
metodo recupera semplicemente il valore memorizzato all'interno dell'oggetto Optional
.
Optional<T> findAny()
metodo
Il findAny()
metodo restituisce qualsiasi elemento dal flusso e termina lì. Questo metodo è simile a findFirst()
, ma è ottimo per i flussi utilizzati in operazioni parallele.
Durante l'elaborazione di flussi in parallelo, potrebbe essere che un elemento sia già stato trovato in qualche parte di un flusso, ma non è ancora chiaro se sia il primo o meno.
Se molti elementi corrispondono a tutti i filtri ed è importante che il programmatore ottenga esattamente il primo di essi, allora il findFirst()
metodo è quello che dovrebbe essere chiamato. Se il programmatore sa che in realtà 0 o 1 elemento corrisponderà a tutti i filtri, allora è sufficiente semplicemente chiamare findAny()
- e questo sarà più veloce.
Optional<T> min(Comparator<T>)
metodo
Il min()
metodo utilizza un comparator
oggetto per confrontare tutti gli elementi nel flusso e restituisce l'elemento minimo. Il modo più conveniente per definire un oggetto comparatore è con una funzione lambda.
Esempio di ricerca della stringa più breve:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();
Optional<T> max(Comparator<T>)
metodo
Il max()
metodo utilizza un comparator
oggetto per confrontare tutti gli elementi nel flusso e restituisce l'elemento massimo. Il modo più conveniente per definire un oggetto comparatore è con una funzione lambda.
Esempio di ricerca della stringa più lunga:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();
GO TO FULL VERSION