Collectors.groupingBy功能和对字段求和
.collect(Collectors.groupingBy(Point::getName, Collectors.summingInt(Point::getCount)));
我有一个Point对象列表,我想按某个键(name字段)分组并按count该类的字段求和。上面的代码完成了这项工作,但返回了一个Point对象映射。但是,我想要Point返回的对象列表-而不是 map。
使用 java 8 流执行此操作的最干净方法是什么?
例子:
input = [pt("jack", 1), pt("jack", 1), pt("jack", 1)]
result = [pt("jack", 3)]
谢谢
回答
您可以使用Collectors.toMap()合并函数作为参数。
如果您添加一个函数来求和count字段:
public class Point {
//...
public static Point sum(Point p1, Point p2) {
return new Point(p1.getName(), p1.getCount()+p2.getCount());
}
}
然后你可以在toMap():
List<Point> list = Collections.nCopies(10, new Point("jack", 1));
Collection<Point> output = list.stream()
.collect(Collectors.toMap(Point::getName, Function.identity(), Point::sum)) // results as Map<String, Point> {"jack", Point("jack",10)}
.values(); // to get the Point instances
System.out.println(output);
输出:
[Point [name=jack, count=10]]
- The `sum()` function should create a new `Point` instance instead of modifying incoming arguments. That would also be important when using parallel streams. If the amount of newly created objects ever becomes a concern, a `collect` based approach should be used.