Как конвертировать карту > к карте > используя поток Java8 - PullRequest
0 голосов
/ 16 января 2020

Как преобразовать 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

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Использование потоков здесь может быть не таким уж тривиальным или даже необходимым. В основном вам нужно сначала отобразить X, Y и Z на кортежи, а затем реконструировать «перевернутую» карту дальше вниз по течению. Это не будет слишком сложно сделать, но, вероятно, не облегчит чтение или повышение производительности.

Вместо этого вы можете сделать что-то вроде следующего, чтобы использовать лямбда-выражения, а также интерфейсы функций:

<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;
}
0 голосов
/ 16 января 2020

Может помочь что-то вроде следующего кода:

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;
}
...