简体   繁体   English

如何转换地图<X, Map<Y,Z> &gt; 到地图<Y, Map<X,Z> &gt; 使用 Java8 流

[英]How to convert Map<X, Map<Y,Z>> to Map<Y, Map<X,Z>> using Java8 stream

How to convert Map<X, Map<Y,Z>> to Map<Y, Map<X,Z>> using Java8 stream.如何使用 Java8 流将Map<X, Map<Y,Z>>Map<Y, Map<X,Z>>

Input:输入:

{A : {B : C, D : E}} // Here B and D are the Key of inner map for A key
{F : {B : G, D : H}} // Here B and D are the Key of inner map for F key

Output:输出:

{B : {A : C, F : G}} // Here A and F are the Key of inner map for B key
{D : {A : E, F : H}} // Here A and F are the Key of inner map for D key

Something like the following code could help:类似以下代码的内容可能会有所帮助:

public static <X, Y, Z> Map<Y, Map<X, Z>> convert(Map<X, Map<Y, Z>> map) {
    return map.entrySet().stream()
            .flatMap(e -> e.getValue().entrySet().stream()
                    .map(en -> new AbstractMap.SimpleEntry<>(en.getKey(),
                            new AbstractMap.SimpleEntry<>(e.getKey(), en.getValue()))))
            .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
                    ent -> constructInnerMap(ent.getValue().getKey(), ent.getValue().getValue()),
                    (xzMap1, xzMap2) -> {
                        xzMap2.putAll(xzMap1);
                        return xzMap2;
                    }));
}

public static <X, Z> Map<X, Z> constructInnerMap(X x, Z z) {
    Map<X, Z> map = new HashMap<>();
    map.put(x, z);
    return map;
}

Using streams here might not be that trivial or even necessary.在这里使用流可能不是那么简单,甚至没有必要。 You'd basically have to first map X, Y and Z to tuples and then reconstruct the "inverted" map further downstream.您基本上必须首先将 X、Y 和 Z 映射到元组,然后再向下游重建“反转”映射。 This wouldn't be too hard to do but would probably not make it easier to read or increase performance.这不会太难做,但可能不会使它更容易阅读或提高性能。

Instead you could do something like the following to leverage lambdas as well as function interfaces:相反,您可以执行以下操作来利用 lambda 以及函数接口:

<X, Y, Z> Map<Y, Map<X, Z>> invert(Map<X, Map<Y, Z>> map) {
    //create a target map
    Map<Y, Map<X, Z>> target = new HashMap<>();

    //loop over the outer and inner entry sets 
    map.entrySet().forEach(outer -> outer.getValue().entrySet().forEach(
        //put the entries into the target map as needed while creating new nested maps as needed
        inner -> target.computeIfAbsent(inner.getKey(), k -> new HashMap<>() )
                       .put(outer.getKey(), inner.getValue())
    ));

    return target;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM