1. Raccolta di elementi

Infine, abbiamo raggiunto il metodo più interessante della Streamclasse, il collect()metodo. Viene utilizzato per passare dai flussi alle nostre raccolte familiari: , List<T>e altri.Set<T>Map<T, R>

Il collect()metodo prende un collectoroggetto speciale come argomento. Questo oggetto legge tutti i dati dal flusso, li converte in un tipo specifico di raccolta e li restituisce. E poi il metodo collect stesso restituisce questa raccolta.

Tutto questo viene fatto in modo piuttosto fluido: il collectortipo dell'oggetto è Collector<T, A, R>. Come puoi vedere, ha tre parametri di tipo. L'ultimo parametro di tipo ( R) è di solito un tipo come List<T>. Ciò significa che il compilatore può utilizzare questo tipo per determinare il tipo restituito corretto per il collect()metodo stesso.

Spero che tu non sia troppo confuso. In ogni caso, non è necessario creare oggetti Collector da soli. CollectorsSaranno sufficienti gli oggetti già pronti restituiti dai metodi statici della classe.

Classe collezionisti

La Collectorsclasse ha diversi metodi statici che restituiscono oggetti di raccolta già pronti, qualcosa per ogni occasione. Qui prenderemo in considerazione i più importanti.

toList()
Un oggetto che converte uno stream in un elenco ( List<T>)
toSet()
Un oggetto che converte uno stream in un set ( Set<T>)
toMap()
Un oggetto che converte uno stream in una map( Map<K, V>)
joining()
Concatena gli elementi di un flusso in una singola stringa
mapping()
Converte gli elementi di una stringa in aMap<K, V>
groupingBy()
Raggruppa gli elementi e restituisceMap<K, V>

2. Conversione di un flusso in un elenco

Di seguito è riportato un tipico esempio di utilizzo di un flusso e di conversione del risultato in un elenco

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

Abbiamo un flusso dalla raccolta. Quindi abbiamo ottenuto un nuovo flusso conservando solo le stringhe il cui primo carattere è maiuscolo. Quindi tutti i dati di quel flusso vengono raccolti in una raccolta, che viene quindi restituita.



3. Conversione di un flusso in un set

Di seguito è riportato un tipico esempio di utilizzo di un flusso e di conversione del risultato in un set

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

Tutto è molto simile al codice per convertire uno stream in un List, solo che usiamo un diverso oggetto raccoglitore, che viene restituito dal toSet()metodo.



4. Conversione di un flusso in una mappa

Ma convertire un flusso in una mappa è un po' più difficile. Ogni voce in una mappa è composta da due elementi: una chiave e un valore. Dobbiamo capire come definiremo la chiave e il valore per ogni elemento nel flusso.

Esempio:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

Diamo un'occhiata a cosa sta succedendo qui.

Nella prima riga, usiamo map(...)per convertire ogni stringa in un array di stringhe. Usando il metodo split, dividiamo ogni stringa in due parti.

Nella seconda riga passiamo al filter()metodo solo quegli array che contengono esattamente due elementi. La d==3stringa viene suddivisa in un array di tre elementi, che non corrisponde al filtro.

E infine, nell'ultima riga, convertiamo lo stream in un file Map<String, String>. Due funzioni vengono passate al toMap()metodo. Per ogni elemento del flusso, la prima funzione deve restituire la chiave e la seconda restituisce il valore .

Il primo elemento di ogni array ("a", "b", "c") sarà la nostra chiave, e il secondo elemento di ogni array ("2", "3", "4") sarà il nostro valore.



5. Conversione di un flusso in una stringa

Un altro interessante oggetto da collezione è restituito da Collectors.joining(). Converte tutti gli elementi di un flusso in Stringe li concatena in una singola stringa. Esempio

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );