簡體   English   中英

如何在 java 中創建嵌套列表對象的 Map?

[英]How can I create a Map of my nested List objects in java?

我有一個列表: List<XNode> nodes ,每個XNode都有一個ArrayList<XNode> children; int id; 作為成員變量。 如何在 java 中創建所有節點的Map<ParentId, ChildId>

首先,如果每個節點中有一個子節點列表,則不可能為每個 childId 創建一個 parentId 的map ,因為通常情況下,一個parentId鍵可能有多個childId值,並且必須以某種方式解決此沖突。

因此,一個Map<Integer, List<Integer>>其中List<Integer>包含所有孩子的 id,或者一個List<List<Integer>> (其中內部List<Integer>包含一對parentIdchildId )可能被創建。

最后,需要定義結果是包含還是葉子 區別可以描述為:有它們的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:

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

Output 用於給定輸入(10 個鍵,13 個值):

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


構建對列表的示例:

  • 按廣度遍歷List<XNode>
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())
        ));
}

Output:

葉(寬度):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<XNode> (列表中的每個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)
        ));
}

Output:

葉(深度):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))
    );
}

Output:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM