Java流或映射按键合并

时间:2017-03-08 19:57:59

标签: java java-stream

将键键值“55”,“55004”,“550009”,“550012”等Map键值合并到一个键中的最简单方法是:“55”以及所有键的总和那些值()。

我正在尝试使用containsKey或修剪密钥的方法。很难想到这一点。

也许是flatMap来平整地图并减少。

@Test
public void TestM(){
        Map<String,Object> map1 = new HashMap();
        map1.put("55", 3453.34);
        map1.put("55001", 5322.44);
        map1.put("55003", 10112.44);
        map1.put("55004", 15555.74);
        map1.put("77", 1000.74); // instead of 1000 it should be ~1500
        map1.put("77004", 444.74);
        map1.put("77003", 66.74);
        // in real example I'll need "77" and "88" and "101" etc. 
        // All of which has little pieces like 77004, 77006

        Map<String,Double> SumMap = new HashMap<String, Double>();

        SumMap = map1.entrySet().stream().map
                   (e->e.getValue()).reduce(0d, Double::sum);
       // INCORRECT
       // REDUCE INTO ONE KEY startsWith 55

        System.out.println("Map: " + SumMap);
       // RESULT should be :
       // Map<String, Double> result = { "55": TOTAL }
       // real example might be "77": TOTAL, "88": TOTAL, "101": TOTAL         
       //(reducing away the "77004", "88005" etc.)
} 

基本上,此代码会将子项目总数减少并滚动到更大的键中。

1 个答案:

答案 0 :(得分:5)

看起来您可以使用Collectors.groupingBy

它需要函数,这将允许我们决定哪些元素属于同一组。来自同一组的元素的此类函数应始终返回相同的值,该值将用作结果映射中的键。在您的情况下,您似乎想要将具有相同前两个字符的元素分组存储在键中,这表示映射到substring(0,2)

当我们已经有办法确定哪些元素属于同一个组时,我们现在可以指定我们希望map如何收集它们。默认情况下,它会将它们收集在列表中,以便我们进行key->[elemnt0, element1, ...]映射 但是我们可以通过提供我们自己的收集器来指定您自己处理来自同一组的元素的方式。由于我们想要创建值的总和,我们可以使用Collectors.summingDouble(mappingToDouble)

样本:

Map<String, Double> map1 = new HashMap<>();
map1.put("661", 123d);
map1.put("662", 321d);
map1.put("55", 3453.34);
map1.put("55001", 5322.44);
map1.put("55003", 10112.44);
map1.put("55004", 15555.74);

Map<String, Double> map = map1.entrySet()
        .stream()
        .collect(
            Collectors.groupingBy(
                entry -> entry.getKey().substring(0, 2), 
                Collectors.summingDouble(Map.Entry::getValue)
            )
        );

System.out.println(map);

输出:{66=444.0, 55=34443.96}