和上一篇中类似的代码, 如下:

List<Buss> st = new ArrayList<>();
bussList.stream()
        // 模拟需要name和another两个字段确定一条记录的情况
        .collect(Collectors.groupingBy(Buss::groupField))
        .forEach((k,v) -> {
            Optional<Buss> sum = v.stream().reduce((v1,v2) -> {
                // 示例
                v1.setExample("example value")
                
                v1.setCount(v1.getCount()+v2.getCount());
                v1.setValue(v1.getValue()+v2.getValue());
                return v1;
            });
            st.add(sum.orElse(new Buss("other", 0, 0.0, 0, -1)));
        });
System.out.println(st);

这里的使用注意点: 上面setExample()方法, 包括reduce()里面的所有方法, 如果groupingBy出来的结果只有一条, 那么里面的代码不会被执行.

  • 实际使用中, 我对于几条操作结果进行groupingBy之后, 需要将一些字段累加合并成一条记录, 如果entity中有一个字段用于记录一共合并了多少条记录, 我的做法是首先
Map<String, Long> countMap = dataList.stream().collect(Collectors.groupingBy(Buss::groupField, Collectors.counting()));

计算得出当前groupField下每个field对应的记录条数

然后这样set:

...
// 这里 k 就是上面 forEach((k, v) -> {...}) 的 k
v1.setCount(String.valueOf(countMap.get(k)))
...

如果当前的groupField下只有一条记录, 那么reduce不会被执行, count始终为null, 多条记录时则可以正常运行.

最终我给count设置了初始值1, 暂时解决了问题.