Java 数据结构:地图、收集器、分组方式

Java 数据结构:地图、收集器、分组方式,java,java-stream,Java,Java Stream,有人能帮我做地图、收藏家和分组吗 代码可在此处找到: //TODO:具有相同billNumber、日期和customerId的合计账单 Map Map=bills.stream().collect(收集器.groupingBy(Bill::getBillNumber, reduceing(BigDecimal.ZERO,Bill::getNetAmount,BigDecimal::add)); 我想把账单的净金额加起来,但第一笔账单应该按账单号、日期和客户ID加起来 因此,该计划的结果应该是:

有人能帮我做地图、收藏家和分组吗

代码可在此处找到:

//TODO:具有相同billNumber、日期和customerId的合计账单
Map Map=bills.stream().collect(收集器.groupingBy(Bill::getBillNumber,
reduceing(BigDecimal.ZERO,Bill::getNetAmount,BigDecimal::add));
我想把账单的净金额加起来,但第一笔账单应该按账单号、日期和客户ID加起来

因此,该计划的结果应该是: 30.50

34.50

15:00

10点


目前它仅按billNumber进行聚合。

首先创建一个复合键:

//@AllArgsConstructor // better to use Lombok if it's possible
//@Getter
//@EqualsAndHashCode
public class CompositeBillKey {
    private final Integer billNumber;
    private final Date billDate;
    private final String customerId;

    public Integer getBillNumber() {
        return billNumber;
    }

    public Date getBillDate() {
        return billDate;
    }

    public String getCustomerId() {
        return customerId;
    }

    public CompositeBillKey(Integer billNumber, Date billDate, String customerId) {
        this.billNumber = billNumber;
        this.billDate = billDate;
        this.customerId = customerId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CompositeBillKey that = (CompositeBillKey) o;
        return Objects.equals(billNumber, that.billNumber) && Objects.equals(billDate, that.billDate) && Objects.equals(customerId, that.customerId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(billNumber, billDate, customerId);
    }
}
然后你可以做:

Map<CompositeBillKey, BigDecimal> billNumberToNetAmount = bills.stream()
        .collect(Collectors.groupingBy(b -> 
                      new CompositeBillKey(b.getBillNumber(), b.getBillDate(), b.getCustomerId()),
                Collectors.reducing(BigDecimal.ZERO, Bill::getNetAmount, BigDecimal::add)));
Map<CompositeBillKey, BigDecimal> billNumberToNetAmount = bills.stream()
        .collect(Collectors.groupingBy(b -> 
                      new CompositeBillKey(b.getBillNumber(), b.getBillDate(), b.getCustomerId()),
                Collectors.reducing(BigDecimal.ZERO, Bill::getNetAmount, BigDecimal::add)));
30.50
34.50
15.00
10.00