当前位置: 首页 > 知识库问答 >
问题:

如何在java中将树结构转换成节点流

马清野
2023-03-14

我想转换Java8节点流中的一棵树。

下面是一个存储数据的节点树,可以选择:

public class SelectTree<D> {

  private D data;

  private boolean selected = false;

  private SelectTree<D> parent;

  private final List<SelectTree<D>> children = new ArrayList<>();

  public SelectTree(D data, SelectTree<D> parent) {
    this.data = data;
    if (parent != null) {
      this.parent = parent;
      this.parent.getChildren().add(this);
    }
  }

  public D getData() {
    return data;
  }

  public void setData(D data) {
    this.data = data;
  }

  public boolean isSelected() {
    return selected;
  }

  public void setSelected(boolean selected) {
    this.selected = selected;
  }

  public SelectTree<D> getParent() {
    return parent;
  }

  public void setParent(SelectTree<D> parent) {
    this.parent = parent;
  }

  public List<SelectTree<D>> getChildren() {
    return children;
  }

  public boolean isRoot() {
    return this.getParent() == null;
  }

  public boolean isLeaf() {
    return this.getChildren() == null || this.getChildren().isEmpty();
  }
}

我想获取所选数据的集合

我想做这样的事情:

  public static void main(String[] args) {
    SelectTree<Integer> root = generateTree();
    
    List<Integer> selectedData = root.stream()
            .peek(node -> System.out.println(node.getData()+": "+node.isSelected()))
            .filter(node-> node.isSelected())
            .map(node-> node.getData())
            .collect(Collectors.toList()) ;
    
    System.out.println("\nselectedData="+selectedData);
  }

  private static SelectTree<Integer> generateTree() {
    SelectTree<Integer> n1 = new SelectTree(1, null);
    SelectTree<Integer> n11 = new SelectTree(11, n1);
    SelectTree<Integer> n12 = new SelectTree(12, n1);
    n12.setSelected(true);
    SelectTree<Integer> n111 = new SelectTree(111, n11);
    n111.setSelected(true);
    SelectTree<Integer> n112 = new SelectTree(112, n11);
    SelectTree<Integer> n121 = new SelectTree(121, n12);
    SelectTree<Integer> n122 = new SelectTree(122, n12);
    return n1;
  }

问题是找到stream()的实现,我想我可以帮助一些人分享我的解决方案,我很想知道是否有一些问题或更好的方法来做到这一点。

起初,它是用于primefaceTreeNode的,但我将问题推广到所有类型的树。

共有3个答案

郭鸿信
2023-03-14

使用任何节点类的更通用方法是为方法添加一个参数,该参数返回子级:

public class TreeNodeStream {
  public static <T> Stream<T> of(T node, Function<T, Collection<? extends T>> childrenFunction) {
    return Stream.concat( //
      Stream.of(node), //
      childrenFunction.apply(node).stream().flatMap(n -> of(n, childrenFunction)));
  }
}

使用文件的示例:

TreeNodeStream.of(
  new File("."), f -> f.isDirectory() ? Arrays.asList(f.listFiles()) :
                                        Collections.emptySet())
  .filter(f -> f.getName().endsWith(".java"))
  .collect(Collectors::toList);
翟淮晨
2023-03-14

我发现stream()的这个实现,它是DFS树遍历:

public class SelectTree<D> {

  //...

  public Stream<SelectTree<D>> stream() {
    if (this.isLeaf()) {
      return Stream.of(this);
    } else {
      return this.getChildren().stream()
                .map(child -> child.stream())
                .reduce(Stream.of(this), (s1, s2) -> Stream.concat(s1, s2));
    }
  }
}

如果不能像prime faces < code > TreeNode (< code > org . prime faces . model . TreeNode )那样更改树实现,可以在另一个类中定义一个方法:

  public Stream<TreeNode> stream(TreeNode parentNode) {
    if(parentNode.isLeaf()) {
      return Stream.of(parentNode);
    } else {
      return parentNode.getChildren().stream()
                .map(childNode -> stream(childNode))
                .reduce(Stream.of(parentNode), (s1, s2) -> Stream.concat(s1, s2)) ;
    }
  }
郭阳曜
2023-03-14

克维萨茨回答的一个小补充。

该实现:

this.getChildren().stream()
        .map(SelectTree::stream)
        .reduce(Stream.of(this), Stream::concat);

会更急切,即。e.整个层次结构将在流创建期间遍历。如果您的层次结构很大,比如说,您正在寻找与某些谓词匹配的单个节点,您可能需要更懒惰的行为:

Stream.concat(Stream.of(this),
              this.getChildren().stream().flatMap(SelectTree::stream));

在这种情况下,在流创建期间只会检索根节点的子节点,搜索节点不一定会导致遍历整个层次结构。

这两种方法都将显示 DFS 迭代顺序。

 类似资料:
  • 我有一个python代码来将字符串数学表达式转换为二叉树并对树的节点进行排序,这样左边的孩子总是比右边的孩子小。我想按以下顺序打印二叉树。 例如,考虑数学表达式((2*75)/4)。buildParseTree()将字符串表达式转换为树并printNodeInLevels()重新排列节点,以便在每个级别上左子节点小于右子节点。操作 我想按如下方式打印它。我该怎么办?因为数学表达式的长度一直在变化,

  • 问题内容: 但是,我仍然无法将csv文件转换为JSON的层次结构。我在stackoverflow上找到的脚本是特定于某个问题的。假设必须对三个变量进行分组: 这将导致这样的JSON文件(据我尝试): 这些必须分组为嵌套结构,例如: 我尝试了该站点上的每个脚本,但是无法创建可以使flare.json这样的通用函数。我可以发布代码,但这就像上面提供的链接一样。因此,我要求一个简单的代码(或可以帮助我的

  • 扁平数组的结构如上,每个目录下都可以添加数据 如何将这个数组转成树形的结构啊,转成如下的形式 目录层级的name就取对应的 xxxLevelStr

  • 本文向大家介绍在数据结构中将B-Rep转换为树,包括了在数据结构中将B-Rep转换为树的使用技巧和注意事项,需要的朋友参考一下 1 B-rep流 明确指出要建立一个生产程序,将由某种标准多边形格式(例如,波前或java3D obj文件)在外部定义的B-rep导入到我们的几何管道的输入流中。多边形和法线提供的边界表示必须一致地定向。对于主要在计算机图形学中实现的一般归档的几何模型,可能需要过滤输入文

  • 问题内容: 我正在从硬件设备读取8字节的数据。我需要将它们转换为数值。我想将它们转换为适合8个字节的长度。我对Java和低级数据类型操作不是很熟悉。我似乎有两个问题(除了几乎没有有关硬件的文档的事实外),这些字节期望是无符号的,所以我无法进行直接整数转换。我不确定它们是什么字节序。 任何意见,将不胜感激。 最终结束了(摘自一个星期前我可能应该已经读过的一些源代码): 问题答案: 对于字节序,请测试

  • 问题内容: 我正在尝试使用gson将返回的JSON转换为某种数据结构,以便提取有用的数据。 例如: http://search.twitter.com/search.json?q=test&rpp=1 返回值: 最终,我希望能够输出带有发件人名称和推文日期/时间的推文列表。 我已经阅读了gson文档,但是说实话,这让我头疼不已-我那里有很多新概念。 我是否需要定义一个完全映射到JSON结构的类,以