Collectors es una de las clases de utilidad en JDK que contiene muchas funciones de utilidad. Se usa principalmente con Stream API como paso final. En este artículo, estudiaremos diferentes métodos en la clase colectora.
Cuando se trata del estilo funcional de programación en Java, normalmente tenemos pocas funciones que usamos ampliamente y esas funciones son filter() , map() , reduce() y collect() que pertenecen a Streams API . Los métodos collect() y reduce() se llaman métodos de terminal porque aquí, la operación termina con algún resultado. Las funciones asociadas con Collectors generalmente se usan dentro de los métodos collect(). La clase Collectors es parte del paquete Stream y se puede importar como:
import static java.util.stream.Collectors.*;
Jerarquía de clases:
java.lang.Object ↳ java.util.stream ↳ class Collectors
Sintaxis:
public final class Collectors extends Object
Métodos dentro de la clase Collectors
Consideremos una clase City , que tiene atributos como nombre y temperatura que se inicializan con el constructor parametrizado. Observaremos los diferentes métodos disponibles en la clase de coleccionistas usando este ejemplo.
A continuación se muestra la implementación de la clase City:
// Java program to implement a // City class // Defining a city class public class City { // Initializing the properties // of the city class private String name; private double temperature; // Parameterized constructor to // initialize the city class public City(String name, double temperature) { this.name = name; this.temperature = temperature; } // Getters to get the name and // temperature public String getName() { return name; } public Double getTemperature() { return temperature; } // Overriding the toString method // to return the name and temperature @Override public String toString() { return name + " --> " + temperature; } }
Antes de entrar en los diferentes métodos, creemos una lista de ciudades con nombre y temperatura. A continuación se muestra la implementación de un método para crear una lista de ciudades con nombre y temperatura:
// Java program to create a list // of cities with name and // temperature // Function to create a list of // cities with name and temperature private static List<City> prepareTemperature() { List<City> cities = new ArrayList<>(); cities.add(new City("New Delhi", 33.5)); cities.add(new City("Mexico", 14)); cities.add(new City("New York", 13)); cities.add(new City("Dubai", 43)); cities.add(new City("London", 15)); cities.add(new City("Alaska", 1)); cities.add(new City("Kolkata", 30)); cities.add(new City("Sydney", 11)); cities.add(new City("Mexico", 14)); cities.add(new City("Dubai", 43)); return cities; }
Los siguientes son los diversos métodos para realizar operaciones en las ciudades anteriores:
1. Collector<T, ?, List<T>> toList(): Transforma los elementos de entrada en una nueva Lista y devuelve un Collector. Aquí, T es el tipo de los elementos de entrada. En el siguiente ejemplo, estamos tratando de procesar la lista de ciudades cuya temperatura es superior a 10 y obtener solo los nombres de las ciudades.
Para hacerlo, usamos filter() para aplicar la verificación de filtro de temperatura, usamos map() para transformar el nombre de la ciudad y usamos collect() para recopilar estos nombres de ciudades. Ahora, este método collect() se usa básicamente para recopilar los elementos pasados a través de la transmisión y sus diversas funciones y devolver una instancia de List .
// Java program to implement the // toList() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // The following statement filters // cities having temp > 10 // The map function transforms only // the names of the cities // The collect function collects the // output as a List System.out.println(prepareTemperature().stream() .filter(f -> f.getTemperature() > 10) .map(f -> f.getName()) .collect(Collectors.toList())); } }
Producción:
[Nueva Delhi, México, Nueva York, Dubái, Londres, Calcuta, Sídney, México, Dubái]
Aquí, la ciudad de Alaska no está presente en la salida porque su temperatura se inicializó como 1.
2. Collector<T, ?, Set<T>> toSet(): Transforma los elementos de entrada en un nuevo Set y devuelve un Collector. Este método devolverá la instancia de Set y no contiene ningún duplicado.
// Java program to implement the // toSet() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Here, we have applied the filter // to get the set of the names // of the cities whose temperature // is greater than 10 System.out.println(prepareTemperature() .stream() .filter(f -> f.getTemperature() > 10) .map(f -> f.getName()) .collect(Collectors.toSet())); } }
Producción:
[Nueva York, Nueva Delhi, Londres, México, Kolkata, Dubai, Sydney]
Aquí, podemos notar en la salida que México y Dubai no se han repetido.
3. Collector<T, ?, C> toCollection(Supplier <C> collectionFactory): transforma los elementos de entrada en una nueva colección y devuelve un Collector. Si observamos los métodos toList() y toSet() discutidos anteriormente, no tenemos control sobre sus implementaciones. Entonces, con toCollection() podemos lograr una implementación personalizada donde C es el tipo de la colección resultante y T es el tipo de los elementos de entrada.
// Java program to implement the // toCollection() method import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Here, a list of all the names // have been returned System.out.println(prepareTemperature() .stream() .map(f -> f.getName()) .collect(Collectors.toCollection(List::new))); } }
Producción:
[Nueva Delhi, México, Nueva York, Dubái, Londres, Alaska, Calcuta, Sídney, México, Dubái]
De manera similar, podemos usar todas las demás clases de implementación, como ArrayList , HashSet , TreeSet , etc.
4. Collector<T, ?, Map< K, U>> toMap(Function keyMapper, Function valueMapper): transforma los elementos en un mapa cuyas claves y valores son el resultado de aplicar las funciones del mapeador pasadas a los elementos de entrada y devuelve un Coleccionista. toMap() se utiliza para recopilar entradas de elementos y convertirlos en una instancia de Map. Los métodos toMap() solicitan los siguientes argumentos:
K - Key function U - Value Function BinaryOperator(optional) Supplier(Optional)
Tratemos de entender esto con un ejemplo. Para la lista de ciudades y temperaturas discutida anteriormente, queremos obtener el nombre de la ciudad con la temperatura en el Mapa.
prepareTemperature().stream().filter(city -> city.getTemperature() > 10)
.collect(Collectors.toMap(City::getName, City::getTemperature));
Las declaraciones anteriores funcionan perfectamente si la lista no tiene duplicados. Dado que nuestra lista contiene duplicados, no la filtrará silenciosamente como toSet(). En su lugar, lanza una IllegalStateException. Podemos evitar y solucionar este problema evitando la colisión de claves (en caso de claves duplicadas) con el tercer argumento que es BinaryOperator. Por ejemplo:
// Java program to implement the // Map() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Here, the name and the temperature // are defined as the type City System.out.println(prepareTemperature() .stream() .filter(city -> city.getTemperature() > 10) .collect(Collectors.toMap( City::getName, City::getTemperature, (key, identicalKey) -> key))); } }
Producción:
{Nueva York=13,0, Nueva Delhi=33,5, Londres=15,0, México=14,0, Calcuta=30,0, Dubái=43,0, Sídney=11,0}
El operador binario especifica cómo podemos manejar la colisión. Las declaraciones anteriores seleccionan cualquiera de los elementos en colisión.
5. Coleccionista de recopiladores y luego (coleccionista descendente, finalizador de funciones): este método nos permite realizar otra operación en el resultado después de recopilar el elemento de entrada de la recopilación.
// Java program to implement the // collectingAndThen() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Collects the elements and // counts the occurrences System.out.println(prepareTemperature() .stream() .collect(Collectors.groupingBy( City::getName, Collectors.collectingAndThen( Collectors.counting(), f -> f.intValue())))); } }
Producción:
{Nueva York=1, Nueva Delhi=1, Londres=1, Alaska=1, México=2, Calcuta=1, Dubái=2, Sídney=1}
6. Recuento de colectores(): Cuenta el número de elementos de entrada de tipo T y devuelve un Colector. Este método se utiliza en el caso de que queramos agrupar y contar el número de veces que cada ciudad está presente en la colección de elementos.
// Java program to implement the // counting() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { System.out.println(prepareTemperature() .stream() .collect(Collectors.groupingBy( City::getName, Collectors.counting()))); } }
Producción:
{Nueva York=1, Nueva Delhi=1, Londres=1, Alaska=1, México=2, Calcuta=1, Dubái=2, Sídney=1}
Podemos ver que las ciudades México y Dubai cuentan 2, y el resto están disponibles una vez. Y el tipo de devolución de groupingBy es Map .
7. Collector <T, ?, Map<K, List>> groupingBy(Function classifier): realiza una operación de agrupación en elementos de entrada de tipo T. La agrupación de elementos se realiza según la función de clasificador pasada y devuelve el Collector con el resultado. en un Mapa.
// Java program to implement the // groupingBy() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { System.out.println(prepareTemperature() .stream() .collect(Collectors.groupingBy(City::getName))); } }
Producción:
{Nueva York=[Nueva York –> 13,0], Nueva Delhi=[Nueva Delhi –> 33,5], Londres=[Londres –> 15,0], Alaska=[Alaska –> 1,0], México=[México –> 14,0, México –> 14.0], Calcuta=[Calcuta –> 30.0], Dubai=[Dubai –> 43.0, Dubai –> 43.0], Sydney=[Sydney –> 11.0]}
En el ejemplo anterior, se han agrupado ciudades como México y Dubai, el resto de los grupos contiene solo una ciudad porque están todos solos. El tipo de devolución de groupingBy() anterior es Map<String, List> .
8. Collector <T, ?, Map> groupingBy(Function classifier, Collector downstream): realiza una operación de agrupación en elementos de entrada de tipo T. La agrupación de los elementos se realiza según la función de clasificador aprobada y luego realiza una operación de reducción en los valores asociados con una clave determinada según el recopilador descendente especificado y devuelve el recopilador con el resultado en un mapa.
9. Collector groupingBy (Function classifier, Supplier mapFactory, Collector downstream): realiza una operación de agrupación en elementos de entrada de tipo T, la agrupación de elementos se realiza según la función de clasificador aprobada y luego realiza una operación de reducción en los valores asociados con un clave dada según el recopilador descendente especificado y devuelve el recopilador.
10. Unión de colector(): concatena los elementos de entrada en una string y devuelve un colector.
11. Unión de recopiladores (delimitador CharSequence): concatena los elementos de entrada, separados por el delimitador especificado, y devuelve un recopilador.
// Java program to implement the // joining() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Concatenate the collection with // comma System.out.println(prepareTemperature() .stream() .filter(city -> city.getTemperature() > 10) .map(f -> f.getName()) .collect(Collectors.joining(", "))); } }
Producción:
Nueva Delhi, México, Nueva York, Dubái, Londres, Calcuta, Sídney, México, Dubái
12. Unión de recopiladores (delimitador CharSequence, prefijo CharSequence, sufijo CharSequence): concatena los elementos de entrada, separados por el delimitador especificado, según el prefijo y el sufijo especificados, y devuelve un recopilador.
// Java program to implement the // joining() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { System.out.println(prepareTemperature() .stream() .filter(city -> city.getTemperature() > 10) .map(f -> f.getName()) .collect(Collectors.joining(" ", "Prefix:", ":Suffix"))); } }
Producción:
Prefijo:Nueva Delhi México Nueva York Dubái Londres Calcuta Sídney México Dubái:Sufijo
13. Asignación de colectores (asignador de funciones, colector descendente): transforma un colector de los elementos de entrada de tipo U en uno de los elementos de entrada de tipo T mediante la aplicación de una función de asignación a cada elemento de entrada antes de la transformación.
// Java program to implement the // mapping() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { System.out.println(prepareTemperature() .stream() .collect(Collectors.groupingBy( City::getName, Collectors.mapping( City::getTemperature, Collectors.toList())))); } }
Producción:
{Nueva York=[13,0], Nueva Delhi=[33,5], Londres=[15,0], Alaska=[1,0], México=[14,0, 14,0], Calcuta=[30,0], Dubái=[43,0, 43,0], Sídney =[11.0]}
En el resultado anterior, cada grupo de ciudades contiene solo la temperatura, y esto se hace con la ayuda del método
mapeo() , que toma dos argumentos de función de tipo función y colector. El método de mapeo anterior devuelve una lista y, finalmente, el tipo de devolución del método groupingBy() anterior se convierte en Map<String, List> . También podemos usar el método toSet() para obtener el conjunto de elementos en lugar de la lista de la siguiente manera:
// Java program to implement the // joining() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { System.out.println(prepareTemperature() .stream() .collect(Collectors.groupingBy( City::getName, Collectors.mapping( City::getTemperature, Collectors.toSet())))); } }
Producción:
{Nueva York=[13,0], Nueva Delhi=[33,5], Londres=[15,0], Alaska=[1,0], México=[14,0], Calcuta=[30,0], Dubái=[43,0], Sídney=[11,0] }
Si observamos la salida y la comparamos con la anterior, los duplicados se han eliminado porque ahora es un conjunto. El tipo de retorno de groupingBy() anterior ahora se convierte en Map<String, Set> .
14. Collector<T, ?, Map<Boolean, List>> particióningBy(predicado predicado): divide los elementos de entrada según el predicado pasado, los transforma en un mapa y devuelve el recopilador.
// Java program to implement the // partitioningBy() method import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class GFG { public static void main(String[] args) { // Here, we are partitioning the list // in two groups i.e., Cities having // temperatures more than 15 // and other than that. System.out.println(prepareTemperature() .stream() .collect(Collectors.partitioningBy( city -> city.getTemperature() > 15))); } }
Producción:
{false=[México–> 14.0, Nueva York–> 13.0, Londres–> 15.0, Alaska–> 1.0, Sydney–> 11.0, México–> 14.0], true=[Nueva Delhi–> 33.5, Dubai–> 43.0, Calcuta–> 30.0, Dubái–> 43.0]}
15. Particionamiento del colector por (predicado predicado, colector descendente): divide los elementos de entrada según el predicado pasado, recopila los valores de cada partición según otro recopilador y los transforma en un mapa cuyos valores son los resultados de la reducción descendente y luego devuelve Collector.
16. Collector averagingDouble(ToDoubleFunction mapper): Realiza el promedio de los elementos de entrada de tipo Double y devuelve el Collector como resultado.
17. Collector averagingInt(ToIntFunction mapper): Realiza el promedio de los elementos de entrada de tipo Int y devuelve el Collector como resultado.
18. Collector averagingLong(ToLongFunction mapper): Realiza el promedio de los elementos de entrada de tipo Long y devuelve el Collector como resultado.
19. Collector<T, ?, ConcurrentMap<K, List>> groupingByConcurrent(Function classifier): realiza una operación de agrupación en los elementos de entrada de tipo T, la agrupación de elementos se realiza según la función de clasificador pasada y devuelve Collector concurrente.
20. Collector<T, ?, ConcurrentMap> groupingByConcurrent(Function classifier, Collector downstream): realiza una operación de agrupación en los elementos de entrada de tipo T, la agrupación de elementos se realiza según la función de clasificador aprobada y luego realiza una operación de reducción en los valores asociados con una clave determinada según el recopilador descendente especificado y devuelve un recopilador concurrente.
21. Collector groupingByConcurrent(Function classifier, Supplier mapFactory, Collector downstream): realiza una operación de agrupación en elementos de entrada de tipo T, la agrupación de elementos se realiza según la función de clasificador aprobada y luego realiza una operación de reducción en los valores asociados con una clave determinada según el recopilador descendente especificado y devuelve un recopilador concurrente.
22. Reducción del colector (BinaryOperator op): realiza una reducción de sus elementos de entrada según el BinaryOperator pasado y devuelve un colector.
23. Reducción del colector (identidad T, operación BinaryOperator): realiza una reducción de sus elementos de entrada según el BinaryOperator pasado y según la identidad pasada y devuelve Collector.
24. Collector<T, ?, Optional> maxBy(Comparator comparador): produce el elemento máximo según el comparador dado, devuelve un colector opcional.
25. Collector<T, ?, Optional> minBy(Comparator comparador): Produce el elemento mínimo según el Comparator dado, devuelve un Collector opcional.
26. Collector<T, ?, ConcurrentMap> toConcurrentMap(Function keyMapper, Function valueMapper) : transforma los elementos en un ConcurrentMap cuyas claves y valores son los resultados de las funciones del mapeador pasadas a los elementos de entrada y devuelve un Collector concurrente.
Referencia: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
Publicación traducida automáticamente
Artículo escrito por asadaliasad y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA