从Map <String,Map <String,Integer >>流中收集Map <String,Integer>

时间:2019-10-14 11:42:14

标签: java java-stream collectors

我有一个嵌套的地图,键为员工名称,值为另一个图,键为公司名称,值作为多年的工作经验,如下所示

Map<String, Map<String, Integer>> map = new HashMap<>();
    Map<String, Integer> innerMap1 = new HashMap<>();
    innerMap1.put("INfosys", 2);
    innerMap1.put("Volvo", 2);
    innerMap1.put("MH", 3);
    innerMap1.put("Piterion", 1);

    Map<String, Integer> innerMap2 = new HashMap<>();
    innerMap2.put("Tata", 2);
    innerMap2.put("Bosch", 1);
    innerMap2.put("Amber", 1);
    innerMap2.put("E2", 1);

    map.put("Rahul", innerMap1);
    map.put("Amrita", innerMap2);

现在,我的函数应该返回一个以员工姓名为键,总经验为值的Map。如何使用Java流(在单个流中)

public Map<String, Integer> getEmployeesWithExp(Map<String, Map<String, Integer>> map) {
    map.entrySet().stream().
                        ...

    return null;
}

4 个答案:

答案 0 :(得分:4)

可能有多种方法,但是您可以collect将条目{{}}放入新映射并将内部映射的值减少为整数,例如像这样:

Map<String, Integer> result = 
           map.entrySet().stream()
              .collect( 
                  Collectors.toMap(e -> e.getKey(), //or Map.Entry::getKey
                                    e -> e.getValue().values().stream()
                                                      .reduce(0, Integer::sum)));

答案 1 :(得分:1)

这是我第一次尝试将流与地图一起使用,这是一个很好的练习,谢谢。

但是,我只在一个流中做不到。该解决方案具有一个主流和一个内部流。

顺便说一下,我使用了org.apache.commons.lang3.tuple.Pair

Map<String, Integer> result = map.entrySet().stream()
        .map(entry -> Pair.of(entry.getKey(), entry.getValue().values().stream().reduce(0, Integer::sum)))
        .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

它回答了

 "Amrita" → 5
 "Rahul" → 8

我认为这是正确的。 :D

答案 2 :(得分:1)

这对于用于解决方案的循环很简单:-

    Map<String, Integer> finalMap = new HashMap<>();
    for (Entry<String, Map<String, Integer>> entry : map.entrySet()) {
        Integer exp = 0;
        for (Entry<String, Integer> entry2 : entry.getValue().entrySet()) {
            exp += entry2.getValue();
        }
        finalMap.put(entry.getKey(), exp);
    }

输出-{Amrita = 5,Rahul = 8}

答案 3 :(得分:0)

可以通过简单的方式完成:-

#include <cstring> // for strlen() and strcpy()

std::vector<char*> Split(std::string input) {
  std::vector<char*> ret;
  std::istringstream f(input);
  std::string s;
  while (getline(f, s, ' ')) {
    char* buf = new char[strlen(s.c_str()) + 1]; // +1 for terminating null-character
    strcpy(buf, s.c_str());
    ret.push_back(buf);
  }
  return ret;
}