我有一个容器列表,每个容器可以有一个父容器,也可以没有父容器。我想将此列表转换为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轻松做到这一点?