将对象列表转换为Map <Parent,List <Descendant >>

时间:2019-07-17 09:07:36

标签: java java-stream grouping

我有一个容器列表,每个容器可以有一个父容器,也可以没有父容器。我想将此列表转换为Map,其中的键是最老的祖先/父级,值是该祖先的所有后代的列表。

我尝试了以下代码,该代码几乎可以按预期工作,但是如果这些孩子也是其他孩子的父母,它也会收集孩子作为父键:

public static void main(String[] args) {
    Container c1 = new Container("c1");
    Container c11 = new Container("c1_1");
    Container c111 = new Container("c1_1_1");
    Container c12 = new Container("c1_2");
    c11.setParent(c1);
    c111.setParent(c11);
    c12.setParent(c1);

    Container c2 = new Container("c2");
    Container c21 = new Container("c2_1");
    Container c22 = new Container("c2_2");
    c21.setParent(c2);
    c22.setParent(c2);


    List<Container> containers = Lists.newArrayList(c1, c11, c111, c12, c2, c21, c22);

    System.out.println("All containers: " + containers);

    Map<Container, List<Container>> parentsAndChildren = containers.stream()
            .collect(Collectors.groupingBy(container -> container.getParent() == null ? container : container.getParent(), Collectors.mapping(container -> container, Collectors.toList())));

    System.out.println("Ancestor / Descendants: " + parentsAndChildren);
}

@Data
@RequiredArgsConstructor
private static final class Container {
    private final String key;
    private Container parent;

    public String toString() {
        return key;
    }
}

这将产生以下输出:

All containers: [c1, c1_1, c1_1_1, c1_2, c2, c2_1, c2_2]
Ancestor / Descendants: {c1_1=[c1_1_1], c2=[c2, c2_1, c2_2], c1=[c1, c1_1, c1_2]}

预期输出为:

All containers: [c1, c1_1, c1_1_1, c1_2, c2, c2_1, c2_2]
Ancestor / Descendants: {c2=[c2_1, c2_2], c1=[c1_1, c1_1_1, c1_2]}

请注意,c1_1_1是最早的祖先c1的直接后代。有没有一种方法可以使用Java 8 Stream轻松做到这一点?

0 个答案:

没有答案