【问题标题】:How can I create a Map of my nested List objects in java?如何在 java 中创建嵌套 List 对象的 Map?
【发布时间】:2021-06-25 23:36:48
【问题描述】:

我有一个列表:List<XNode> nodes,每个XNode 都有一个ArrayList<XNode> children;int id; 作为成员变量。如何在 java 中创建我所有节点的Map<ParentId, ChildId>

【问题讨论】:

    标签: java list recursion java-stream


    【解决方案1】:

    首先,如果每个节点中有一个 list 子节点,则不可能为每个 childId 创建一个 parentId 的 map,因为通常情况下是 parentId键可能有多个childId 值,必须以某种方式解决此冲突。

    因此,可以创建 Map<Integer, List<Integer>>,其中 List<Integer> 包含所有孩子的 id,或者创建 List<List<Integer>>(其中内部 List<Integer> 包含一对 parentIdchildId)。

    最后,需要定义结果是包含roots还是leafs。 区别可以描述为:有它们的parentId = null和非空childId叶子总是有非空parentIdchildId可能是null.

    假设输入节点列表是这样定义的:

    List<XNode> list = Arrays.asList(
        new XNode(1, Arrays.asList(new XNode(11, Arrays.asList(new XNode(111), new XNode(112))), new XNode(12), new XNode(13))),
        new XNode(2),
        new XNode(3, Arrays.asList(new XNode(31, Arrays.asList(new XNode(311)))))
    );
    

    那么地图可以如下创建:

    Map<Integer, List<Integer>> map = list.stream()
        .flatMap(Main::flatMapEntry)
        .collect(Collectors.toMap(
            Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new
        ));  
    System.out.println("map example: " + map);
    

    使用递归方法flatMapEntry:

    static Stream<Map.Entry<Integer, List<Integer>>> flatMapEntry(XNode node) {
        return node.getChildren().isEmpty()
            ? Stream.of(Map.entry(node.getId(), Collections.emptyList()))
            : Stream.concat(
                Stream.of(Map.entry(
                    node.getId(), 
                    node.getChildren().stream()
                        .map(XNode::getId)
                        .collect(Collectors.toList())
                )),
                node.getChildren().stream().flatMap(Main::flatMapEntry)
            );
    }
    

    给定输入的输出(10 个键,13 个值):

    地图示例:{1=[11, 12, 13], 11=[111, 112], 111=[], 112=[], 12=[], 13=[], 2=[], 3=[31], 31=[311], 311=[]}


    构建对列表的示例:

    • 按广度遍历List&lt;XNode&gt;
    List<List<Integer>> leafsBreadth = flatList(list).collect(Collectors.toList());
    
    System.out.println("leafs(breadth): " + leafsBreadth.size() + ": " + leafsBreadth);
    // ---
    static Stream<List<Integer>> flatList(List<XNode> list) {
        return list.stream()
            .flatMap(x -> x.getChildren().isEmpty() 
                ? Stream.of(Arrays.asList(x.getId(), null)) 
                : Stream.concat(x.getChildren().stream()
                    .map(c -> Arrays.asList(x.getId(), c.getId())),
                    flatList(x.getChildren())
            ));
    }
    

    输出:

    叶子(宽度):13:[[1, 11], [1, 12], [1, 13], [11, 111], [11, 112], [111, null], [112, null], [12, null], [13, null], [2, null], [3, 31], [31, 311], [311, null]]


    • 按深度遍历List&lt;XNode&gt;(列表中的每个XNode):
    List<List<Integer>> leafsDepth = list.stream()
        .flatMap(x -> flatChildren(x)).collect(Collectors.toList());
    System.out.println("leafs(depth):   " + leafsDepth.size() + ": " + leafsDepth);
    // ----
    static Stream<List<Integer>> flatChildren(XNode node) {
        return node.getChildren().isEmpty()
            ? Stream.of(Arrays.asList(node.getId(), null))
            : node.getChildren().stream().flatMap(x -> Stream.concat(
                Stream.of(Arrays.asList(node.getId(), x.getId())),
                flatChildren(x)
            ));
    }
    

    输出:

    叶子(深度):13:[[1, 11], [11, 111], [111, null], [11, 112], [112, null], [1, 12], [12, null], [1, 13], [13, null], [2, null], [3, 31], [31, 311], [311, null]]


    • 按深度构建
    List<List<Integer>> rootsDepth = list.stream()
        .flatMap(x -> flatRoots(null, x)) // using null for missing parentId
        .collect(Collectors.toList());
    System.out.println("roots(depth):   " + rootsDepth.size() + ": " + rootsDepth);
    // ----
    static Stream<List<Integer>> flatRoots(Integer parentId, XNode node) {
        return Stream.concat(
            Stream.of(Arrays.asList(parentId, node.getId())),
            node.getChildren().stream().flatMap(x -> flatRoots(node.getId(), x))
        );
    }
    

    输出:

    根(深度): 10: [[null, 1], [1, 11], [11, 111], [11, 112], [1, 12], [1, 13], [null, 2], [null, 3], [3, 31], [31, 311]]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 2021-06-09
      • 2014-01-10
      相关资源
      最近更新 更多