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.
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
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]}
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]}
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 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]}}
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}
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}
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]}
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]}
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