假设有一个List<Object>
,并且Object
包含两种方法:getUserId
和getPoints
。
考虑List<Object>
包含三个对象,并且它们包含以下数据:
userId A; 3 points
userId A; 5 points
userId B; 1 point
在正确收集了此信息之后,我期望有一个Map<String, Integer>
如下所示:
A: 8,
B: 1
我正在尝试使用Java的8个功能接口(流)进行此操作,因为我只需要最终结果,而在它们之间也不需要任何映射。如果没有其他方法,我愿意对此进行修改。 我首先想到了这个:
this.service.getListObject()
.stream()
.collect(Collectors.toMap(Object::getUserId, Object::getPoints));
但是,这显示不足,因为它将始终用最新值替换密钥,从而产生:
A: 5,
B: 1
如何调整Collectors.toMap()
中的最后几位以根据已存储在映射中的值自动增加其值,以便产生上面的结果?
答案 0 :(得分:6)
将Collectors.groupingBy
与Collectors.summingInt
一起用作下游收集器:
this.service.getListObject()
.stream().collect(Collectors.groupingBy(
Object::getUserId, Collectors.summingInt(Object::getPoints)));
答案 1 :(得分:4)
要更正您刚开始的实现,您需要一个合并功能,如下:
...stream().collect(Collectors.toMap(CustomObject::getUserId,
CustomObject::getPoints, Integer::sum)); // <--- summing value here
最终也可以用groupingBy
和summingInt
的组合来表示。