当前位置: 首页 > 知识库问答 >
问题:

数据结构:map、Collectors、groupingBy

查锦程
2023-03-14
    //TODO: aggregate bills that have same billNumber, date and customerId
    Map<Integer, BigDecimal> map = bills.stream().collect(Collectors.groupingBy(Bill::getBillNumber,
        Collectors.reducing(BigDecimal.ZERO, Bill::getNetAmount, BigDecimal::add)));

我想合计帐单的净额,但第一张帐单应该按billNumber、date和CustomerID合计。

所以这个程序的结果应该是:30.50

34.50

15.00

10.00

目前它只按BillNumber聚合。

共有1个答案

祁宾白
2023-03-14

首先创建一个复合键:

//@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)));

输出:

30.50
34.50
15.00
10.00
 类似资料:
  • Set 基本用法 ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 Set本身是一个构造函数,用来生成Set数据结构。 var s = new Set(); [2, 3, 5, 4, 5, 2, 2].map(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4 上面代码通过ad

  • 与Set类似,ES6同样实现了一个Map类,即我们所说的字典 是一种以 键-值对 形式存储数据的数据结构 ,就如同我们平时查看通讯录一样,要找一个电话,首先先找到该号码的机主名字,名字找到了,紧接着电话号码也就有了。 这里的键就是你用来查找的东西,本例中指代的就是名字,值就是查找得到的结果,也就是对应的电话号码。 在JavaScript 中的 Object 类就是以字典的形式设计的,下面我们将会借

  • 在前面两章中,我们已经研究了可以用于实现 Map 抽象数据类型的几个数据结构。二叉搜索表,散列表,二叉搜索树和平衡二叉搜索树。 总结这一节,让我们总结 Map ADT 定义的关键操作的每个数据结构的性能(见 Table 1)。

  • 本文向大家介绍详解ES6中的 Set Map 数据结构学习总结,包括了详解ES6中的 Set Map 数据结构学习总结的使用技巧和注意事项,需要的朋友参考一下 ES6中的 Set 数据结构 ES6 新增了一种 Set 数据结构。它类似数组。 最重要的一点是 Set中的结构成员没有重复的, 可用这点 一行代码实现数组去重。 Set 本身是一个构造函数。通过 new Set() 来创建Set结构。 通

  • 顺序结构 顺序栈(Sequence Stack) SqStack.cpp 顺序栈数据结构和图片 typedef struct { ElemType *elem; int top; int size; int increment; } SqStack; 队列(Sequence Queue) 队列数据结构 typedef struct { ElemType * elem; int fron

  • 数据结构 Collection 和 Sequence Clojure 常用的数据结构有 List, Map, Vector, Set. 他们都属于 Collection, 之间的关系大致是这样: 属于 Clojure 当中实现的数据结构都是 Collection. 编码当中会遇到 Host 平台的数据类型, 不属于 Collection. 实现了 Collection 的接口的数据结构都支持这些函