0

如何转换Map<X, Map<Y,Z>>Map<Y, Map<X,Z>>使用 Java8 流。

输入:

{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

输出:

{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
4

2 回答 2

0

在这里使用流可能不是那么微不足道甚至是必要的。您基本上必须首先将 X、Y 和 Z 映射到元组,然后再向下游重建“反转”映射。这不会太难做,但可能不会使它更容易阅读或提高性能。

相反,您可以执行以下操作来利用 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;
}
于 2020-01-17T06:41:19.343 回答
0

类似以下代码的内容可能会有所帮助:

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;
}
于 2020-01-16T17:32:25.713 回答