Java 8 Java流收集所有子项

Java 8 Java流收集所有子项,java-8,java-stream,hierarchical-data,children,collectors,Java 8,Java Stream,Hierarchical Data,Children,Collectors,我想编写一个Java 8stream().collect函数,该函数返回一个列表,其中包含层次结构中节点的所有子节点和子节点。例如TreeItemgetChildren()和所有子对象的子对象等等,将其缩减为单个列表 顺便说一下,这是我作为泛型方法的最终解决方案。非常有效,非常有用 public static <T> Stream<T> treeStream(T root, boolean includeRoot, Function<T, Stream<?

我想编写一个Java 8
stream().collect
函数,该函数返回一个
列表
,其中包含层次结构中节点的所有子节点和子节点。例如
TreeItem
getChildren()
和所有子对象的子对象等等,将其缩减为单个列表


顺便说一下,这是我作为泛型方法的最终解决方案。非常有效,非常有用

public static <T> Stream<T> treeStream(T root, boolean includeRoot, Function<T, Stream<? extends T>> nextChildren)
{
    Stream<T> stream = nextChildren.apply(root).flatMap(child -> treeStream(child, true, nextChildren));
    return includeRoot ? Stream.concat(Stream.ofNullable(root), stream) : stream;
}

publicstaticstream树(T root,boolean includeRoot,Function您必须使用递归函数展平树。这里有一个示例:

您必须使用递归函数展平树。这里有一个示例:

为了避免堆栈溢出,可以用堆中的队列替换堆栈

此解决方案从迭代器创建流,该迭代器懒洋洋地导航包含中的下一项的树

根据队列的类型,遍历可以是或

类树项{
集合子项=新的ArrayList();
}
河流变平(树根){
迭代器迭代器=新迭代器(){
Queue Queue=newlinkedlist(Collections.singleton(root));//宽度优先
//Queue Queue=Collections.asLifoQueue(新链接列表(Collections.singleton(root));//深度优先
@重写公共布尔值hasNext(){
return!queue.isEmpty();
}
@重写公共树Item next(){
TreeItem next=queue.poll();
queue.addAll(next.children);
下一步返回;
}
};
返回StreamSupport.stream(Spliterators.spliteratorUnknownSize(迭代器,0),false);
}

为了避免堆栈溢出,有一种方法可以将堆栈替换为堆中的队列

此解决方案从迭代器创建流,该迭代器懒洋洋地导航包含中的下一项的树

根据队列的类型,遍历可以是或

类树项{
集合子项=新的ArrayList();
}
河流变平(树根){
迭代器迭代器=新迭代器(){
Queue Queue=newlinkedlist(Collections.singleton(root));//宽度优先
//Queue Queue=Collections.asLifoQueue(新链接列表(Collections.singleton(root));//深度优先
@重写公共布尔值hasNext(){
return!queue.isEmpty();
}
@重写公共树Item next(){
TreeItem next=queue.poll();
queue.addAll(next.children);
下一步返回;
}
};
返回StreamSupport.stream(Spliterators.spliteratorUnknownSize(迭代器,0),false);
}

你能分享你的
TreeItem
类吗(或者,至少,它的相关方法)?@Mureinik“My”TreeItem类是javafx.scene.control.TreeItem。相关方法是getChildren()。你能分享你的
TreeItem
类吗(或者,至少,它的相关方法)?@Mureinik“My”TreeItem类是javafx.scene.control.TreeItem。相关方法是getChildren().没关系,但递归通常是个坏主意,因为堆栈可能会溢出。如果树很深,你可以使用-这里有一个很好的方法来避免堆栈溢出:虽然代码可读性变差。蹦床…我不知道它们,很有趣。没关系,但递归通常是个坏主意,因为堆栈可能会溢出可能会溢出。如果树很深,你可以使用-这里有一个避免堆栈溢出的好方法:代码会变得不那么可读。蹦床…我不知道,很有趣。
class TreeItem {
    Collection<TreeItem> children = new ArrayList<>();
}

Stream<TreeItem> flatten(TreeItem root) {
    Iterator<TreeItem> iterator = new Iterator<TreeItem>() {
        Queue<TreeItem> queue = new LinkedList<>(Collections.singleton(root)); //breadth first
//      Queue<TreeItem> queue = Collections.asLifoQueue(new LinkedList<>(Collections.singleton(root))); //depth first

        @Override public boolean hasNext() {
            return !queue.isEmpty();
        }

        @Override public TreeItem next() {
            TreeItem next = queue.poll();
            queue.addAll(next.children);
            return next;
        }
    };
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
}