Classe di Utilità Collectors per Stream API
Il metodo collect() nella Stream API è già noto come strumento potente per raccogliere gli elementi di uno stream in strutture dati comode. Tuttavia, collect() richiede un'implementazione di Collector, il che può rendere il processo più complesso.
Qui entra in gioco la classe Collectors, che fornisce una serie di implementazioni predefinite per le operazioni più comuni. Semplifica attività come la raccolta dei dati in collezioni, raggruppamento e conteggio, rendendo queste operazioni molto più immediate.
Metodi principali della classe Collectors
La classe Collectors offre numerose soluzioni pronte all'uso, eliminando la necessità di implementare manualmente un Collector. Ecco alcuni dei metodi principali:
La Stream API offre anche il metodo integrato toList(), che hai già utilizzato in precedenza. Questo metodo presenta una sintassi concisa, rendendolo la nostra scelta preferita. Tuttavia, sei libero di utilizzare qualsiasi implementazione che meglio si adatti alle tue esigenze.
Conversione di una Lista in una Mappa
Si consideri una lista di prodotti con i rispettivi prezzi, memorizzati come stringhe nel formato Name=Price. L'obiettivo è creare una Map in cui la chiave rappresenta il nome del prodotto e il valore il suo prezzo.
Main.java
1234567891011121314151617181920package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> productData = List.of("Laptop:1500", "Smartphone:900", "Monitor:1200"); // Convert the list of strings into a `Map` by splitting the string at "=" Map<String, Integer> productPriceMap = productData.stream() .collect(Collectors.toMap( item -> item.split(":")[0], // Key - product name item -> Integer.parseInt(item.split(":")[1]) // Value - price )); System.out.println("Product Map: " + productPriceMap); } }
In questo caso si utilizza toMap() per dividere ciascuna stringa (split("=")) e creare una Map<String, Integer>, dove la chiave è il nome del prodotto e il valore è il prezzo come intero. Ad esempio, la stringa Laptop=1500 viene trasformata in una voce Laptop -> 1500.
Raggruppamento dei prodotti per lettera iniziale
Raggruppamento dei prodotti in base alla prima lettera per identificare quali elementi iniziano con la stessa lettera.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Drone", "Smartphone", "Smartwatch", "Monitor", "Mouse" ); // Grouping products by the first letter of their name Map<Character, List<String>> groupedProducts = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0))); System.out.println("Products grouped by first letter: " + groupedProducts); } }
Il programma crea una List di nomi di prodotti e li raggruppa in base alla prima lettera utilizzando groupingBy(). Il risultato viene memorizzato in una Map, dove la chiave è charAt(0) e il valore è una lista di prodotti corrispondenti. Infine, i prodotti raggruppati vengono stampati.
Suddivisione dei Prezzi
Collectors.partitioningBy è un collettore speciale nella Stream API che suddivide gli elementi in due gruppi in base a un determinato predicato.
Map<Boolean, List<Integer>> partitionedPrices = prices.stream()
.collect(Collectors.partitioningBy(price -> price > 1000));
Restituisce una Map<Boolean, List<T>>, dove true rappresenta gli elementi che soddisfano la condizione, e false rappresenta quelli che non la soddisfano.
Questo è utile per separare i dati, come ad esempio filtrare numeri pari e dispari o prodotti con prezzo alto e basso.
Esempio
Dividiamo i prezzi dei prodotti in due categorie: costosi (superiori a $1000) ed economici ($1000 o meno).
Main.java
123456789101112131415161718package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> prices = List.of(1500, 900, 1200, 1100, 300); // Partition prices into expensive and cheap categories Map<Boolean, List<Integer>> partitionedPrices = prices.stream() .collect(Collectors.partitioningBy(price -> price > 1000)); System.out.println("Expensive products: " + partitionedPrices.get(true)); System.out.print("Cheap products: " + partitionedPrices.get(false)); } }
Il metodo partitioningBy() suddivide la lista dei prezzi in due gruppi. Se un prezzo è maggiore di 1000, viene inserito sotto la chiave true; altrimenti, viene inserito sotto false.
Conteggio dei prodotti
Conteggio del numero di prodotti che iniziano con la stessa lettera.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Dishwasher", "Drone", "Smartphone", "Smartwatch", "Speaker", "Monitor", "Mouse", "Microphone" ); // Count how many products start with each letter Map<Character, Long> countByLetter = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0), Collectors.counting())); System.out.println("Product count by first letter: " + countByLetter); } }
Il programma elabora la List di prodotti utilizzando stream(), quindi applica groupingBy() con charAt(0) per raggruppare le parole in base alla prima lettera. Il collector counting() conteggia quanti prodotti rientrano in ciascun gruppo, e la Map finale memorizza la lettera come chiave e il conteggio come valore.
Unione dei nomi dei prodotti
Concatenazione dei nomi dei prodotti in una singola stringa, separandoli con virgole.
Main.java
12345678910111213141516package com.example; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of("Laptop", "Smartphone", "Monitor"); // Join product names into a single comma-separated string String productNames = products.stream() .collect(Collectors.joining(", ")); System.out.println("Product list: " + productNames); } }
Il metodo Collectors.joining(", ") concatena tutti i nomi dei prodotti in un'unica stringa, separandoli con virgole. Infine, la stringa risultante viene stampata per mostrare l'elenco dei prodotti in un formato leggibile.
1. Cosa fa il seguente codice?
2. Quale metodo di Collectors dovrebbe essere utilizzato per raggruppare i prodotti in base alla loro prima lettera?
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione
Can you show examples of how to use each Collectors method?
What are some common use cases for groupingBy and partitioningBy?
How do I choose between toList(), toSet(), and toMap()?
Awesome!
Completion rate improved to 2.33
Classe di Utilità Collectors per Stream API
Scorri per mostrare il menu
Il metodo collect() nella Stream API è già noto come strumento potente per raccogliere gli elementi di uno stream in strutture dati comode. Tuttavia, collect() richiede un'implementazione di Collector, il che può rendere il processo più complesso.
Qui entra in gioco la classe Collectors, che fornisce una serie di implementazioni predefinite per le operazioni più comuni. Semplifica attività come la raccolta dei dati in collezioni, raggruppamento e conteggio, rendendo queste operazioni molto più immediate.
Metodi principali della classe Collectors
La classe Collectors offre numerose soluzioni pronte all'uso, eliminando la necessità di implementare manualmente un Collector. Ecco alcuni dei metodi principali:
La Stream API offre anche il metodo integrato toList(), che hai già utilizzato in precedenza. Questo metodo presenta una sintassi concisa, rendendolo la nostra scelta preferita. Tuttavia, sei libero di utilizzare qualsiasi implementazione che meglio si adatti alle tue esigenze.
Conversione di una Lista in una Mappa
Si consideri una lista di prodotti con i rispettivi prezzi, memorizzati come stringhe nel formato Name=Price. L'obiettivo è creare una Map in cui la chiave rappresenta il nome del prodotto e il valore il suo prezzo.
Main.java
1234567891011121314151617181920package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> productData = List.of("Laptop:1500", "Smartphone:900", "Monitor:1200"); // Convert the list of strings into a `Map` by splitting the string at "=" Map<String, Integer> productPriceMap = productData.stream() .collect(Collectors.toMap( item -> item.split(":")[0], // Key - product name item -> Integer.parseInt(item.split(":")[1]) // Value - price )); System.out.println("Product Map: " + productPriceMap); } }
In questo caso si utilizza toMap() per dividere ciascuna stringa (split("=")) e creare una Map<String, Integer>, dove la chiave è il nome del prodotto e il valore è il prezzo come intero. Ad esempio, la stringa Laptop=1500 viene trasformata in una voce Laptop -> 1500.
Raggruppamento dei prodotti per lettera iniziale
Raggruppamento dei prodotti in base alla prima lettera per identificare quali elementi iniziano con la stessa lettera.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Drone", "Smartphone", "Smartwatch", "Monitor", "Mouse" ); // Grouping products by the first letter of their name Map<Character, List<String>> groupedProducts = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0))); System.out.println("Products grouped by first letter: " + groupedProducts); } }
Il programma crea una List di nomi di prodotti e li raggruppa in base alla prima lettera utilizzando groupingBy(). Il risultato viene memorizzato in una Map, dove la chiave è charAt(0) e il valore è una lista di prodotti corrispondenti. Infine, i prodotti raggruppati vengono stampati.
Suddivisione dei Prezzi
Collectors.partitioningBy è un collettore speciale nella Stream API che suddivide gli elementi in due gruppi in base a un determinato predicato.
Map<Boolean, List<Integer>> partitionedPrices = prices.stream()
.collect(Collectors.partitioningBy(price -> price > 1000));
Restituisce una Map<Boolean, List<T>>, dove true rappresenta gli elementi che soddisfano la condizione, e false rappresenta quelli che non la soddisfano.
Questo è utile per separare i dati, come ad esempio filtrare numeri pari e dispari o prodotti con prezzo alto e basso.
Esempio
Dividiamo i prezzi dei prodotti in due categorie: costosi (superiori a $1000) ed economici ($1000 o meno).
Main.java
123456789101112131415161718package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> prices = List.of(1500, 900, 1200, 1100, 300); // Partition prices into expensive and cheap categories Map<Boolean, List<Integer>> partitionedPrices = prices.stream() .collect(Collectors.partitioningBy(price -> price > 1000)); System.out.println("Expensive products: " + partitionedPrices.get(true)); System.out.print("Cheap products: " + partitionedPrices.get(false)); } }
Il metodo partitioningBy() suddivide la lista dei prezzi in due gruppi. Se un prezzo è maggiore di 1000, viene inserito sotto la chiave true; altrimenti, viene inserito sotto false.
Conteggio dei prodotti
Conteggio del numero di prodotti che iniziano con la stessa lettera.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Dishwasher", "Drone", "Smartphone", "Smartwatch", "Speaker", "Monitor", "Mouse", "Microphone" ); // Count how many products start with each letter Map<Character, Long> countByLetter = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0), Collectors.counting())); System.out.println("Product count by first letter: " + countByLetter); } }
Il programma elabora la List di prodotti utilizzando stream(), quindi applica groupingBy() con charAt(0) per raggruppare le parole in base alla prima lettera. Il collector counting() conteggia quanti prodotti rientrano in ciascun gruppo, e la Map finale memorizza la lettera come chiave e il conteggio come valore.
Unione dei nomi dei prodotti
Concatenazione dei nomi dei prodotti in una singola stringa, separandoli con virgole.
Main.java
12345678910111213141516package com.example; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of("Laptop", "Smartphone", "Monitor"); // Join product names into a single comma-separated string String productNames = products.stream() .collect(Collectors.joining(", ")); System.out.println("Product list: " + productNames); } }
Il metodo Collectors.joining(", ") concatena tutti i nomi dei prodotti in un'unica stringa, separandoli con virgole. Infine, la stringa risultante viene stampata per mostrare l'elenco dei prodotti in un formato leggibile.
1. Cosa fa il seguente codice?
2. Quale metodo di Collectors dovrebbe essere utilizzato per raggruppare i prodotti in base alla loro prima lettera?
Grazie per i tuoi commenti!