Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java8在HashMaps列表上进行多个聚合_Java_Java 8 - Fatal编程技术网

如何使用Java8在HashMaps列表上进行多个聚合

如何使用Java8在HashMaps列表上进行多个聚合,java,java-8,Java,Java 8,我对java 8实现中HashMap列表的多个聚合有一个问题(首选使用“reduce”函数,但不是必须) 我需要使用拆分(“\u”)[0]”“服务”键名进行多个聚合,如下所示: 假设我的数据结构: List<Map<String, Object>> payments = new ArrayList<>(); for(int i=0 ; ....i++){ Map<String, String> map = new HashMap&

我对java 8实现中HashMap列表的多个聚合有一个问题(首选使用
“reduce”
函数,但不是必须)

我需要使用拆分(“\u”)[0]”“服务”键名进行多个聚合,如下所示:

假设我的数据结构:

 List<Map<String, Object>> payments = new ArrayList<>();
  for(int i=0 ; ....i++){
      Map<String, String> map = new HashMap<>();
      map.put("service","IMAP_"+i);
      map.put("storageValue",<some value>)
      ....
      payments.add(map);
  }
结果应该是:

{
      "payments": [
        {
          "service": "IMAP",
          "storageValue": 30,
          "users": "11"
        },
        {
          "storageValue": 400,
          "service": "Office 365 Exchange",
          "users": "25"
        },
        {
          "storageValue": 50,
          "service": "SalesForce",
          "users": "100"
        }
      ]
    }
应该是

payments.stream().forEach(paymet -> {
                paymet.entrySet().stream().map(....?...).reduce()...
            );

这里有一个不完整的建议,它将
收集器.groupingBy
收集器.reduce
结合起来

Map<String,Optional<Map<String,Object>>> result = 
    payments.stream ().collect(Collectors.groupingBy (map -> map.get ("service").split ("_")[0],
                               Collectors.reducing ((m1,m2)-> {
                                   Map<String,String> m = new HashMap<>();
                                   m.put("service",m1.get("service")); // you may have to remove the _1 suffix
                                   m.put("storageValue",(Integer)m1.get("storageValue")+(Integer)m2.get("storageValue"));
                                   m.put("users",(Integer)m1.get("users")+(Integer)m2.get("users"));
                                   return m;
                               })));
映射结果=
payments.stream().collect(Collectors.groupingBy(map->map.get(“服务”).split(“”)[0],
收集器。减少量((m1,m2)->{
Map m=新的HashMap();
m、 put(“service”,m1.get(“service”);//您可能需要删除_1后缀
m、 put(“storageValue”,(整数)m1.get(“storageValue”)+(整数)m2.get(“storageValue”);
m、 put(“users”,(Integer)m1.get(“users”)+(Integer)m2.get(“users”);
返回m;
})));
请注意,由于
Map
s包含
String
值,因此将这些
Map
的值当作数字来添加有点不方便。您必须进行一些从
String
int
的转换,反之亦然


将每个
映射
转换为具有存储、用户和storageValue属性的某个类的实例可能会有所帮助。然后你可以有一个结合两个这样的实例的方法。

试试这个。这不是优雅:)

首先将
服务
键的值更改为新值

 payments.stream()
            .forEach(item -> item.put("service", item.get("service").split("_")[0]));
然后

HashMap-mapofmap=payments.stream()
.collect(Collectors.toMap(hashMap->hashMap.get(“服务”),
hashMap->(hashMap)hashMap,
YOURCLASS::merge,HashMap::new);
列表结果=新的ArrayList(mapOfMaps.values());
并定义合并两个贴图的方法,如下所示:

private static HashMap<String, String> merge(HashMap<String, String> map1, HashMap<String, String> map2) {
    if (map1.get("service").equals(map2.get("service"))) {
        Long storageValue = Long.valueOf(map1.get("storageValue")) + Long.valueOf(map2.get("storageValue"));
        map1.put("storageValue", storageValue.toString());
        Long users = Long.valueOf(map1.get("users")) + Long.valueOf(map2.get("users"));
        map1.put("users", users.toString());
    }
    return map1;
}
private静态HashMap合并(HashMap-map1、HashMap-map2){
如果(map1.get(“服务”).equals(map2.get(“服务”)){
Long-storageValue=Long.valueOf(map1.get(“storageValue”)+Long.valueOf(map2.get(“storageValue”);
map1.put(“storageValue”,storageValue.toString());
Long users=Long.valueOf(map1.get(“用户”)+Long.valueOf(map2.get(“用户”));
map1.put(“users”,users.toString());
}
返回map1;
}

将其作为对象
{“服务”:“IMAP”、“storageValue”:“30”、“用户”:“11”}
,将大大减轻您的生活。@nullpointer您是对的,但不能忽略的是遗留代码changed@VitalyT当然,这是可以改变的。即使您的职责只涉及这一个操作,您最好先将这些映射转换为有意义类的实例,使用这些实例以可维护的方式执行操作,然后将生成的实例转换回映射。但我怀疑这是代码中唯一可以更改的部分。现在,您将要创建更多的“无法更改的遗留代码”。@Eran假设它是一个整数……我只需要自己进行求和实现吗?我可以改用java8sum实现吗?谢谢:)@vitaly我想什么是整数?你地图的价值?在这种情况下,它必须是一个
映射
,您需要将值强制转换为
整数
,以便执行加法。您是对的,更改为对象…您可以使用求和函数更改答案吗…@vitaly请参见编辑。我没有测试它,所以可能有一些拼写错误。非常感谢,但我想知道我是否可以在java8函数中使用“sum”构建?
HashMap<String, HashMap> mapOfMaps = payments.stream()
            .collect(Collectors.toMap(hashMap -> hashMap.get("service"),
                    hashMap -> (HashMap) hashMap,
                    YOURCLASS::merge, HashMap::new));
List<HashMap> result = new ArrayList<>(mapOfMaps.values());
private static HashMap<String, String> merge(HashMap<String, String> map1, HashMap<String, String> map2) {
    if (map1.get("service").equals(map2.get("service"))) {
        Long storageValue = Long.valueOf(map1.get("storageValue")) + Long.valueOf(map2.get("storageValue"));
        map1.put("storageValue", storageValue.toString());
        Long users = Long.valueOf(map1.get("users")) + Long.valueOf(map2.get("users"));
        map1.put("users", users.toString());
    }
    return map1;
}