Java8如何使用stream和lambda将3级嵌套列表转换为嵌套HashMap

Ash*_*inK 5 java lambda hashmap java-8 java-stream

我正在尝试将 3 级嵌套列表转换为嵌套 HashMap。

其函数声明为:

Map<Key1, Map<Key2, List<String>>> transformToMap (List<Obj1> inputList)

内部inputList有嵌套列表,该列表也有嵌套列表。

我编写的代码使用传统的 for 循环,如下所示:

private Map<Key1 , Map<Key2, List<String>>> reverseLookup(List<Key2> key2List){
    Map<Key1 , Map<Key2, List<String>>>  resultMap = new HashMap<>();
    key2List.forEach(key2->{
        List<ElementObject> elementObjects = key2.getElementObjects();
        elementObjects.forEach(elementObject->{
            final String name = elementObject.getName();
            elementObject.getApplicablePeriods().forEach(applicablePeriod-> {
                Key1 key1 = applicablePeriod.getKey1();
                Map<Key2, List<String>> map2 = resultMap.get(key1);
                if(map2 == null){
                    map2 = new HashMap<>();
                }
                List<String> stringList = map2.get(key2);
                if(stringList == null){
                    stringList = new ArrayList<>();
                }
                stringList.add(name);
                map2.put(key2, stringList);
                resultMap.put(key1, map2);
            });
        });
    });

    return resultMap;
}
Run Code Online (Sandbox Code Playgroud)

其类结构如下:

class Key2{

    List<ElementObject> elementObjects;

    //getters & setters
}

class ElementObject {
    String name;
    //few more params
    List<ApplicablePeriod> applicablePeriods;
     //getters & setters
}

class ApplicablePeriod{
    Key1 key1;
    //getters & setters
}

class Key1{
    //some parameters
    //getters & setters
}
Run Code Online (Sandbox Code Playgroud)

上面的代码满足了我的期望。

使用将其转换为流 lambda 的有效方法是什么Collectors.toMap

我尝试过如下:

inputList
        .stream()
        .flatMap(item -> item.getObj2List().stream())
        .flatMap(nestedItem -> nestedItem.getKeyList().stream())
        .collect(Collectors.toMap(a-> a.get()))
Run Code Online (Sandbox Code Playgroud)

但没有得到下一步应该做什么Collectors.toMap。无法处理final String name = nestedItem.getName();在第三个 for 循环之前使用的内容。

让我知道解决这个问题的方法。

daj*_*vax 0

我没有任何测试数据来查看它是否创建与传统​​代码类似的东西。但看看这个,让我知道是否有帮助:

key2List.stream().flatMap((key2) -> key2.elementObjects.stream().map((element) -> new AbstractMap.SimpleImmutableEntry<>(key2, element)))
    .flatMap((entry) -> entry.getValue().applicablePeriods.stream().map((period) -> new AbstractMap.SimpleImmutableEntry<>(period.key1, new AbstractMap.SimpleImmutableEntry<>(entry.getKey(), entry.getValue().name))))
    .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())))));
Run Code Online (Sandbox Code Playgroud)