Agrégation de listes en Java (Collectors.groupingBy)

Vous pouvez utiliser Collectors.groupingBy pour grouper des listes et obtenir des données de type Map de Key-List. Nous avons compilé un exemple de code pratique.

Objet cible

public class Product {

	private String productId;

	private String productName;

	private String productType;

	private BigDecimal price;
	
	private long qty;

	// getter setter

Créez une liste avec l'image suivante en utilisant l'objet ci-dessus.

1 productName:iPhone X        productType:iPhone    price:120000   qty:2
2 productName:iPhone 8 Plus   productType:iPhone    price:110000   qty:3
3 productName:iPhone 8        productType:iPhone    price:100000   qty:1
4 productName:Galaxy S9       productType:Android   price:100000   qty:4
5 productName:Galaxy S9 plus  productType:Android   price:110000   qty:3
6 productName:Windows phone   productType:Others    price:80000    qty:1
7 productName:Windows phone   productType:Others    price:85000    qty:2

Regroupement d'articles uniques

Regroupez les éléments uniques avec Collectors.groupingBy.

//Regroupement d'articles uniques
Map<String, List<Product>> grpByType = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType));

Résultat de l'exécution:

{iPhone=[productId:001 productName:iPhone X productType:iPhone price:120000 qty:2, productId:002 productName:iPhone 8 Plus productType:iPhone price:110000 qty:3, productId:003 productName:iPhone 8 productType:iPhone price:100000 qty:1], 
 Others=[productId:006 productName:Windows phone productType:Others price:80000 qty:1, productId:007 productName:Windows phone productType:Others price:85000 qty:2], 
 Android=[productId:004 productName:Galaxy S9 productType:Android price:100000 qty:4, productId:005 productName:Galaxy S9 plus productType:Android price:110000 qty:3]}

Regroupement de plusieurs éléments

Méthode 1

Créez une clé composite à l'avance et utilisez cette clé composite lors du regroupement.

//Créer une clé composite
Function<Product, String> compositeKey = prd -> {
	StringBuffer sb = new StringBuffer();
	sb.append(prd.getProductType()).append("-").append(prd.getProductName());
	return sb.toString();
};

//Regroupement avec des clés composées
Map<String, List<Product>> grpByComplexKeys = prdList.stream().collect(
				Collectors.groupingBy(compositeKey));

Résultat de l'exécution:

{iPhone-iPhone 8 Plus=[productId:002 productName:iPhone 8 Plus productType:iPhone price:110000 qty:3], 
 Android-Galaxy S9 plus=[productId:005 productName:Galaxy S9 plus productType:Android price:110000 qty:3], 
 Others-Windows phone=[productId:006 productName:Windows phone productType:Others price:80000 qty:1, productId:007 productName:Windows phone productType:Others price:85000 qty:2], 
 Android-Galaxy S9=[productId:004 productName:Galaxy S9 productType:Android price:100000 qty:4], 
 iPhone-iPhone 8=[productId:003 productName:iPhone 8 productType:iPhone price:100000 qty:1], 
 iPhone-iPhone X=[productId:001 productName:iPhone X productType:iPhone price:120000 qty:2]}

Méthode 2

Créez une classe de clé composite et remplacez hashCode et equals pour comparaison.

public class Keys {
	
	String productType;
	String productName;
	
	public Keys(String productType, String productName) {
		this.productType = productType;
		this.productName = productName;
	}

	@Override
	public int hashCode() {
		//Omis (généré automatiquement à partir de l'IDE)
	}

	@Override
	public boolean equals(Object obj) {
		//Omis (généré automatiquement à partir de l'IDE)
	}

Regroupez par la classe de clé de déchiffrement créée.

//Regroupement avec des clés composées
Map<Keys, List<Product>> grpByComplexKeys = prdList.stream().collect(
				Collectors.groupingBy(prd -> new Keys(prd.getProductType(), prd.getProductName())));

Résultat de l'exécution:

{Android-Galaxy S9 plus=[productId:005 productName:Galaxy S9 plus productType:Android price:110000 qty:3], 
 iPhone-iPhone 8 Plus=[productId:002 productName:iPhone 8 Plus productType:iPhone price:110000 qty:3], 
 Android-Galaxy S9=[productId:004 productName:Galaxy S9 productType:Android price:100000 qty:4], 
 iPhone-iPhone 8=[productId:003 productName:iPhone 8 productType:iPhone price:100000 qty:1], 
 iPhone-iPhone X=[productId:001 productName:iPhone X productType:iPhone price:120000 qty:2], 
 Others-Windows phone=[productId:006 productName:Windows phone productType:Others price:80000 qty:1, productId:007 productName:Windows phone productType:Others price:85000 qty:2]}

Regroupement plusieurs fois

//Regroupement deux fois
Map<String, Map<String, List<Product>>> grpByTypeAndGrpByName = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.groupingBy(Product::getProductName)));

Résultat de l'exécution:

{iPhone={iPhone 8=[productId:003 productName:iPhone 8 productType:iPhone price:100000 qty:1], iPhone X=[productId:001 productName:iPhone X productType:iPhone price:120000 qty:2], iPhone 8 Plus=[productId:002 productName:iPhone 8 Plus productType:iPhone price:110000 qty:3]}, 
 Others={Windows phone=[productId:006 productName:Windows phone productType:Others price:80000 qty:1, productId:007 productName:Windows phone productType:Others price:85000 qty:2]}, 
 Android={Galaxy S9=[productId:004 productName:Galaxy S9 productType:Android price:100000 qty:4], Galaxy S9 plus=[productId:005 productName:Galaxy S9 plus productType:Android price:110000 qty:3]}}

Total du groupe

Total de int, long, etc.

Trouvez la somme de int et long avec Collectors.summingInt et Collectors.summingLong.

//Somme INT
Map<String, Long> grpByTypeSumQty = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.summingLong(Product::getQty)));

Résultat de l'exécution:

{iPhone=6, Others=3, Android=7}

Grand total décimal

Trouvez la somme de Big Decimal avec Collectors.reducing.

//Grand total décimal
Map<Object, BigDecimal> grpByTypeSum = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.reducing(BigDecimal.ZERO, Product::getPrice, BigDecimal::add)));

Résultat de l'exécution:

{iPhone=330000, Others=165000, Android=210000}

Groupe maximum

Valeur maximale de int, long

Utilisez Comparator.comparingInt et Comparator.comparingLong pour trouver la valeur maximale du groupe.

Map<String, Optional<Product>> grpByTypeMaxInt = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.maxBy(Comparator.comparingLong(Product::getQty))));

Résultat de l'exécution:

{iPhone=Optional[productId:002 productName:iPhone 8 Plus productType:iPhone price:110000 qty:3], 
 Others=Optional[productId:007 productName:Windows phone productType:Others price:85000 qty:2], 
 Android=Optional[productId:004 productName:Galaxy S9 productType:Android price:100000 qty:4]}

Valeur maximale de Big Decimal

Vous pouvez obtenir la valeur maximale du groupe avec Comparator.comparing.

Map<String, Optional<Product>> grpByTypeMaxDecimal2 = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.maxBy(Comparator.comparing(Product::getPrice))));

Vous pouvez également utiliser votre propre comparateur.

//Valeur maximale de Big Decimal
Map<String, Optional<Product>> grpByTypeMaxDecimal = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.maxBy(new Comparator<Product>() {

			@Override
			public int compare(Product o1, Product o2) {
				return o1.getPrice().compareTo(o2.getPrice());
			}

		}))
);

Résultat de l'exécution:

{iPhone=Optional[productId:001 productName:iPhone X productType:iPhone price:120000 qty:2], 
 Others=Optional[productId:007 productName:Windows phone productType:Others price:85000 qty:2], 
 Android=Optional[productId:005 productName:Galaxy S9 plus productType:Android price:110000 qty:3]}

Formule complexe

Une formule de calcul (prix unitaire x quantité) est définie à l'avance, et la valeur totale du groupe est calculée à partir de celle-ci.

//Formule de calcul (prix unitaire x quantité)
Function<Product, BigDecimal> calcFunction = prd -> 
				prd.getPrice().multiply(new BigDecimal(prd.getQty()));

//Agrégation
Map<String, BigDecimal> grpByTypeToSum = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType,
					Collectors.reducing(BigDecimal.ZERO, calcFunction, BigDecimal::add)));

Résultat de l'exécution:

{iPhone=670000, Others=250000, Android=730000}

Recommended Posts

Agrégation de listes en Java (Collectors.groupingBy)
Liste des membres ajoutés dans Java 9
Liste des types ajoutés dans Java 9
Partition en Java
Mémorandum Java (liste)
Clonez la liste Java.
Changements dans Java 11
Remplacez List <Optional <T >> par Optional <List <T >> en Java
Fonction de conversion d'objet de liste immuable (immuable) dans Java8
Différence entre les listes d'arry et les listes liées en Java
Traitez n'importe quel nombre de cas dans la liste Java
Taux circonférentiel à Java
FizzBuzz en Java
Ne déclarez pas de variables dans List en Java
Lire JSON en Java
Implémentation de l'interpréteur par Java
Faites un blackjack avec Java
Application Janken en Java
Programmation par contraintes en Java
Mettez java8 dans centos7
NVL-ish guy en Java
Joindre des tableaux en Java
Interface appelable en Java
Commentaires dans la source Java
Fonctions Azure en Java
Formater XML en Java
Simple htmlspecialchars en Java
Implémentation Boyer-Moore en Java
Hello World en Java
Utiliser OpenCV avec Java
Mémorandum WebApi avec Java
Exécuter des commandes en Java (ping)
Divers threads en java
Implémentation du tri de tas (en java)
API Zabbix en Java
Art ASCII à Java
Comparer des listes en Java
POST JSON en Java
Exprimer l'échec en Java
Créer JSON en Java
Manipulation de la date dans Java 8
Utiliser PreparedStatement en Java
Nouveautés de Java 9,10,11
[Mémo] Liste liée Java
Exécution parallèle en Java
Exemple de code pour convertir List en List <String> dans Java Stream
[Java] Conversion de type de liste / type de tableau
Essayez d'utiliser RocksDB avec Java
Lire des fichiers binaires en Java 1
Évitez l'erreur que Yuma a donnée en Java
Obtenir des informations EXIF en Java
[Neta] Sleep Sort en Java
[Java, stream] Trier la liste d'objets en japonais par nom de propriété
Modifier ini en Java: ini4j
L'histoire de Java dans ce monde
Segfo Java en 6 lignes