当前位置: 首页 > 知识库问答 >
问题:

Java 8-如何使用流收集器对映射列表进行分组和求和

林俊英
2023-03-14

我有一个地图列表,并希望对某些列进行分组和求和。

地图列表:

double min=100;
double max=999;
List<Map<String,Object>> positions = new ArrayList<Map<String,Object>>();
for (int i=0; i<10; i++) {
    Map<String,Object> positionRow = new HashMap<String,Object>();
    positionRow.put("id", i+1);
    if ((i+1)%2 == 0)
        positionRow.put("Mod", "Even");
    else
        positionRow.put("Mod", "Odd");
    Random r = new Random();
    double randomValue = min + (max - min) * r.nextDouble();
    positionRow.put("price", randomValue);
    positionRow.put("bigger", (randomValue > 300)?"Y":"N");
    positions.add(positionRow);
}
Map<String, List<Map<String, Object>>> grouped = positions.stream()
        .collect(
                Collectors.groupingBy(m -> m.get("Mod").toString()
                        + "<|>" + m.get("bigger").toString()));
{Even<|>Y=[{Mod=Even, price=872.729803251601, bigger=Y, id=2}, {Mod=Even, price=353.6589309614915, bigger=Y, id=4}, {Mod=Even, price=981.8179976373482, bigger=Y, id=6}, {Mod=Even, price=942.3538966530067, bigger=Y, id=8}, {Mod=Even, price=919.0174189044218, bigger=Y, id=10}], Odd<|>Y=[{Mod=Odd, price=663.7589137270676, bigger=Y, id=1}, {Mod=Odd, price=894.1766799283644, bigger=Y, id=3}, {Mod=Odd, price=905.8003509608488, bigger=Y, id=5}, {Mod=Odd, price=758.3085768816934, bigger=Y, id=7}, {Mod=Odd, price=531.1035747782346, bigger=Y, id=9}]}
{Even<|>Y={sum_price=4069.578047, sum_id=30}, Odd<|>Y={sum_price=3753.148096,sum_id=25}}

共有1个答案

司马璞
2023-03-14

map 不是一个很好的维护对象的类型。这正是具有名称和声明类型的类和字段被发明的原因。收集器所需的代码反映了这一点:

Map<String, Map<String, Object>> grouped = positions.stream()
.collect(Collectors.groupingBy(m -> m.get("Mod")+"<|>"+m.get("bigger"),
    Collector.of(HashMap::new, (m,p)-> {
        m.merge("sum_price", p.get("price"), (a,b)->((Double)a)+((Double)b));
        m.merge("sum_id", p.get("id"), (a,b)->((Integer)a)+((Integer)b));
    }, (m1,m2)-> {
        m1.merge("sum_price", m2.get("sum_price"), (a,b)->((Double)a)+((Double)b));
        m1.merge("sum_id", m2.get("sum_id"), (a,b)->((Integer)a)+((Integer)b));
        return m1;
    })));
 类似资料:
  • 2020-07-08->{0->{hourquarter.first->5.5,ehourquarter.second->10.2,...},1->{ehourquarter.first->33.2,ehourquarter.second->30.1,...},...} 它是一个整数图(小时:从0到23)的局部日期图,二倍的每小时四分之一图。 我需要得到一个包含每个日期累加的map >,这意味着如

  • 我正在使用我有一个类,如下所示: 现在我想做的是: 筛选出senderId无效的记录(使用映射) 下面是我的代码: 这给我带来了一个错误: 错误:(105,90)java:找不到适用于groupingBy(共享[…]的方法gMode,java。util。作用函数)方法java。util。流动收藏家。groupingBy(java.util.function.function)不适用(无法推断类型变

  • 问题内容: 我的清单包含大小等的集合。我尝试这样做,但似乎不起作用。 我想要的最终结果是。 我可以尝试添加在所有的元素和那种出来再做出新的的。但是,有某种班轮吗? 更新: 这可行,但是可以简化吗? 问题答案: @Eugene的回答很甜蜜,因为番石榴很甜。但是,如果您碰巧在类路径中没有番石榴,这是另一种方式: 首先,我将所有集合映射到一个流中,然后对所有元素进行排序,最后,将整个排序后的流收集到集合

  • Java流新手在这里。目前我正在完成本书中关于收集者的第6章(用流收集数据)。 我的对象是这样的。 这样做的目的是得到某种总体总结报告。基本上是一个HashMap 关键1: 投影-表示每个报告中所有投影的总和。 关键2: <代码>票据-表示每个报表中所有票据的总和。 关键3: 收入-表示每个报表的所有收入之和。 现在,我实际上通过创建自定义收集器来进行赋值,称为。 所以我得到的结果是这样的: 所以

  • 假设你有一张这样的物体地图(尽管想象它更大): rtype=133,有两个! 我想对Streams做的是这样的: 我在理解Collectors&groupBy的工作原理时遇到了一些麻烦,但我想这可能会用于本例。 在Java streams API中进行编码的正确方法是什么? 我很难找到类似的地图例子(人们在他们的例子中更多地使用列表)

  • 我有以下两门课: : : 我希望进行流操作,以便: 将映射到中的 的和分别合并到和中,对于所有具有相同id的s 为此,我编写了以下一段代码: 它的工作和输出如下: 但我相信有一种更好的方式可以达到同样的效果。任何一个指针都很好。