簡體   English   中英

Java 8 stream 由多個屬性和總和分組

[英]Java 8 stream group by multiple attributes and sum

我有一個對象列表作為以下對象,我想按 3 個屬性對它們進行分組並將第 4 個屬性相加

public class DTO {
    private final  String at1;
    private final  String at2;
    private final  Integer at3;
    private final  BigDecimal amount;

}

我做了類似以下的事情,但它導致了許多地圖,我無法獲得對金額求和的方法,因為它也需要一些邏輯

List<DTO> list = ...
Map<String, Map<String, Map<Integer, List<DTO>>>> groupedItems =
                list.stream()
                .collect(
                Collectors.groupingBy(e -> e.getAt1(), 
                    Collectors.groupingBy(e -> e.getAt2(),
                                Collectors.groupingBy( e -> e.getAt3()))));

如何獲得具有求和邏輯的分組列表列表?

您可以創建一個構造函數,其中包含要分組的三個屬性:

public DTO(String at1, String at2, Integer at3) {
    this.at1 = at1;
    this.at2 = at2;
    this.at3 = at3;
}

然后你可以使用:

Map<DTO, BigDecimal> groupedItems = list.stream()
        .collect(Collectors.groupingBy(e -> new DTO(e.getAt1(), e.getAt2(), e.getAt3()),
                Collectors.reducing(
                        BigDecimal.ZERO,
                        DTO::getAmount,
                        BigDecimal::add)));

我假設您正在覆蓋 DTO class 中的equalshashCode


例子:

List<DTO> list = new ArrayList<>();
list.add(new DTO("a", "b", 1, BigDecimal.valueOf(10)));
list.add(new DTO("z", "y", 4, BigDecimal.valueOf(20)));
list.add(new DTO("a", "b", 1, BigDecimal.valueOf(30)));
list.add(new DTO("a", "b", 1, BigDecimal.valueOf(40)));

輸出

DTO{at1='a', at2='b', at3=1, amount=null} - 80
DTO{at1='z', at2='y', at3=4, amount=null} - 20

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM