首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Map<X、Map<Y、Z>到Map<Y、Map<X、Z>

Map<X、Map<Y、Z>到Map<Y、Map<X、Z>
EN

Stack Overflow用户
提问于 2019-07-16 16:19:29
回答 2查看 97关注 0票数 5

我想要切换map的键和其中的一个map:

代码语言:javascript
复制
Map<X, Map<Y, Z> -> Map<Y, Map<X, Z>

我尝试过使用流,但无法创建内部映射,也无法分别从原始内部映射中访问键和值。

//到目前为止我已经尝试过了:

代码语言:javascript
复制
originalMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-16 16:24:20

有点复杂,但它是有效的:

代码语言:javascript
复制
Map<Y,Map<X,Z>> out =
      originalMap.entrySet()
                 .stream()
                 .flatMap(e -> e.getValue()
                                .entrySet()
                                .stream()
                                .map(e2 -> {
                                    Map<X,Z> m = new HashMap<>();
                                    m.put(e.getKey(),e2.getValue());
                                    return new SimpleEntry<>(e2.getKey(),m);}))
                 .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1,v2)->{v1.putAll(v2);return v1;}));

基本上,它将原始Map条目的Stream转换为所需输出Map的平面条目的Stream (其中每个内部Map只有一个Entry),并使用具有合并函数的toMap收集器来合并与同一外部键相对应的内部Map

例如,使用以下输入Map运行此代码:

代码语言:javascript
复制
Map<String,Map<Integer,Double>> originalMap = new HashMap<>();
Map<Integer,Double> inner1 = new HashMap<>();
Map<Integer,Double> inner2 = new HashMap<>();
Map<Integer,Double> inner3 = new HashMap<>();
originalMap.put("aa",inner1);
originalMap.put("bb",inner2);
originalMap.put("cc",inner3);
inner1.put(10,10.0);
inner1.put(20,20.0);
inner1.put(30,30.0);
inner2.put(10,40.0);
inner2.put(20,50.0);
inner2.put(30,60.0);
inner3.put(10,70.0);
inner3.put(20,80.0);
inner3.put(30,90.0);

Map<Integer,Map<String,Double>> out =
    originalMap.entrySet()
               .stream()
               .flatMap(e -> e.getValue()
                              .entrySet()
                              .stream()
                              .map(e2 -> {
                                  Map<String,Double> m = new HashMap<>();
                                  m.put(e.getKey(),e2.getValue());
                                  return new SimpleEntry<>(e2.getKey(),m);}))
               .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1,v2)->{v1.putAll(v2);return v1;}));
System.out.println (out);

将输出:

代码语言:javascript
复制
{20={aa=20.0, bb=50.0, cc=80.0}, 10={aa=10.0, bb=40.0, cc=70.0}, 30={aa=30.0, bb=60.0, cc=90.0}}

编辑:

如果您使用的是Java9或更高版本,则可以使用Map.of来简化代码:

代码语言:javascript
复制
Map<Y,Map<X,Z>> out =
      originalMap.entrySet()
                 .stream()
                 .flatMap(e -> e.getValue()
                                .entrySet()
                                .stream()
                                .map(e2 -> new SimpleEntry<>(e2.getKey(),Map.of(e.getKey(),e2.getValue()))))
                 .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1,v2)->{v1.putAll(v2);return v1;}));
票数 4
EN

Stack Overflow用户

发布于 2019-07-16 17:02:36

对我来说,实际上没有流,这要容易得多;但仍然使用java-8特性(这个例子取自另一个答案):

代码语言:javascript
复制
    Map<Integer, Map<String, Double>> result = new HashMap<>();

    originalMap.forEach((key, value) -> {
        value.forEach((innerKey, innerValue) -> {

            Map<String, Double> map = new HashMap<>();
            map.put(key, innerValue);

            result.merge(innerKey, map, (left, right) -> {
                left.putAll(right);
                return left;
            });
        });
    });

    System.out.println(result);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57052934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档