Java按颜色分组Widget并汇总属性生成Map的实现方法
按Widget的colour分组并汇总legs和arms属性值的Stream实现方法
步骤1:修正Widget类的getter/setter
原示例代码中存在属性名与setter方法名不匹配的问题(比如colour属性对应setColor,legs属性对应setLeg),先修正为标准的getter/setter:
class Widget { private String colour; private Double legs; private Double arms; public String getColour() { return colour; } public void setColour(String colour) { this.colour = colour; } public Double getLegs() { return legs; } public void setLegs(Double legs) { this.legs = legs; } public Double getArms() { return arms; } public void setArms(Double arms) { this.arms = arms; } }
步骤2:定义汇总结果类
创建一个WidgetSummary类来存储每组的legs和arms总和,同时提供合并方法:
class WidgetSummary { private Double totalLegs = 0.0; private Double totalArms = 0.0; // 合并单个Widget到当前汇总结果 public void merge(Widget widget) { this.totalLegs += widget.getLegs(); this.totalArms += widget.getArms(); } // 合并两个汇总结果(支持并行流) public WidgetSummary combine(WidgetSummary other) { this.totalLegs += other.totalLegs; this.totalArms += other.totalArms; return this; } @Override public String toString() { return String.format("Legs(%.0f), Arms(%.0f)", totalLegs, totalArms); } }
步骤3:Stream分组汇总实现
使用Collectors.groupingBy按colour分组,下游收集器用Collector.of自定义汇总逻辑:
public class WidgetGroupingDemo { public static void main(String[] args) { List<Widget> widList = new ArrayList<>(); Widget wid1 = new Widget(); wid1.setColour("Yello"); wid1.setLegs(10.0); wid1.setArms(10.0); Widget wid2 = new Widget(); wid2.setColour("Yello"); wid2.setLegs(20.0); wid2.setArms(30.0); Widget wid3 = new Widget(); wid3.setColour("White"); wid3.setLegs(20.0); wid3.setArms(30.0); // 分组并汇总 Map<String, WidgetSummary> result = widList.stream() .collect(Collectors.groupingBy( Widget::getColour, Collector.of( WidgetSummary::new, WidgetSummary::merge, WidgetSummary::combine ) )); // 打印结果 result.forEach((colour, summary) -> System.out.println("\"" + colour + "\" : " + summary)); } }
运行结果
"Yello" : Legs(30), Arms(40) "White" : Legs(20), Arms(30)
替代方案:使用reducing收集器
如果不想自定义收集器,也可以用Collectors.reducing实现:
Map<String, WidgetSummary> result = widList.stream() .collect(Collectors.groupingBy( Widget::getColour, Collectors.reducing( new WidgetSummary(), widget -> { WidgetSummary summary = new WidgetSummary(); summary.merge(widget); return summary; }, WidgetSummary::combine ) ));
内容的提问来源于stack exchange,提问作者Mohit H
相关产品推荐
相关产品推荐

