Sie können "Collectors.groupingBy" verwenden, um Listen zu gruppieren und Kartentypdaten der Schlüsselliste abzurufen. Wir haben einen praktischen Beispielcode zusammengestellt.
public class Product {
	private String productId;
	private String productName;
	private String productType;
	private BigDecimal price;
	
	private long qty;
	// getter setter
Erstellen Sie mit dem obigen Objekt eine Liste mit dem folgenden Bild.
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
Gruppieren Sie einzelne Elemente mit "Collectors.groupingBy".
//Gruppierung einzelner Elemente
Map<String, List<Product>> grpByType = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType));
Ausführungsergebnis:
{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]}
Erstellen Sie im Voraus einen zusammengesetzten Schlüssel und verwenden Sie diesen zusammengesetzten Schlüssel beim Gruppieren.
//Erstellen Sie einen zusammengesetzten Schlüssel
Function<Product, String> compositeKey = prd -> {
	StringBuffer sb = new StringBuffer();
	sb.append(prd.getProductType()).append("-").append(prd.getProductName());
	return sb.toString();
};
//Gruppieren mit zusammengesetzten Schlüsseln
Map<String, List<Product>> grpByComplexKeys = prdList.stream().collect(
				Collectors.groupingBy(compositeKey));
Ausführungsergebnis:
{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]}
Erstellen Sie eine zusammengesetzte Schlüsselklasse und überschreiben Sie hashCode und equals zum Vergleich.
public class Keys {
	
	String productType;
	String productName;
	
	public Keys(String productType, String productName) {
		this.productType = productType;
		this.productName = productName;
	}
	@Override
	public int hashCode() {
		//Ausgelassen (automatisch aus IDE generiert)
	}
	@Override
	public boolean equals(Object obj) {
		//Ausgelassen (automatisch aus IDE generiert)
	}
Gruppieren Sie nach der erstellten Entschlüsselungsschlüsselklasse.
//Gruppieren mit zusammengesetzten Schlüsseln
Map<Keys, List<Product>> grpByComplexKeys = prdList.stream().collect(
				Collectors.groupingBy(prd -> new Keys(prd.getProductType(), prd.getProductName())));
Ausführungsergebnis:
{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]}
//Zweimal gruppieren
Map<String, Map<String, List<Product>>> grpByTypeAndGrpByName = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.groupingBy(Product::getProductName)));
Ausführungsergebnis:
{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]}}
Finden Sie die Summe von int und long mit Collectors.summingInt und Collectors.summingLong.
//INT Summe
Map<String, Long> grpByTypeSumQty = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.summingLong(Product::getQty)));
Ausführungsergebnis:
{iPhone=6, Others=3, Android=7}
Finden Sie die Summe von Big Decimal mit Collectors.reducing.
//Große Dezimalzahl
Map<Object, BigDecimal> grpByTypeSum = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.reducing(BigDecimal.ZERO, Product::getPrice, BigDecimal::add)));
Ausführungsergebnis:
{iPhone=330000, Others=165000, Android=210000}
Verwenden Sie Comparator.comparingInt und Comparator.comparingLong, um den Maximalwert der Gruppe zu ermitteln.
Map<String, Optional<Product>> grpByTypeMaxInt = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.maxBy(Comparator.comparingLong(Product::getQty))));
Ausführungsergebnis:
{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]}
Den Maximalwert der Gruppe erhalten Sie mit Comparator.comparing.
Map<String, Optional<Product>> grpByTypeMaxDecimal2 = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType, 
					Collectors.maxBy(Comparator.comparing(Product::getPrice))));
Sie können auch Ihren eigenen Komparator verwenden.
//Maximalwert von 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());
			}
		}))
);
Ausführungsergebnis:
{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]}
Eine Berechnungsformel (Einheitspreis x Menge) wird im Voraus definiert und der Gesamtwert der Gruppe wird damit berechnet.
//Berechnungsformel (Stückpreis x Menge)
Function<Product, BigDecimal> calcFunction = prd -> 
				prd.getPrice().multiply(new BigDecimal(prd.getQty()));
//Anhäufung
Map<String, BigDecimal> grpByTypeToSum = prdList.stream().collect(
				Collectors.groupingBy(Product::getProductType,
					Collectors.reducing(BigDecimal.ZERO, calcFunction, BigDecimal::add)));
Ausführungsergebnis:
{iPhone=670000, Others=250000, Android=730000}
        Recommended Posts