reduce()的使用注意点
和上一篇中类似的代码, 如下:
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, 暂时解决了问题.