如果我有一个仍然排序但扁平化的层次结构 - 我如何使用 Java Streams API 创建父/子结构?一个例子: 我要怎么走
-,A,Foo
A,A1,Alpha1
A,A2,Alpha2
-,B,Bar
B,B1,Bravo1
B,B2,Bravo2
到
-
A
A1,Alpha1
A2,Alpha2
B
B1,Bravo1
B2,Bravo2
一种简单的非流方式是跟踪父列并查看它是否已更改。
我已经尝试了各种 Collectors 和 groupingBy 方法,但还没有找到如何做。
List<Row> list = new ArrayList<>();
list.add(new Row("-", "A", "Root"));
list.add(new Row("A", "A1", "Alpha 1"));
list.add(new Row("A", "A2", "Alpha 2"));
list.add(new Row("-", "B", "Root"));
list.add(new Row("B", "B1", "Bravo 1"));
list.add(new Row("B", "B2", "Bravo 2"));
//Edit
Map<Row, List<Row>> tree;
tree = list.stream().collect(Collectors.groupingBy(???))
最佳答案
您可以为每个 Row
创建一个 Map
,并按名称索引:
Map<String,Row> nodes = list.stream().collect(Collectors.toMap(Row::getName,Function.identity()));
getName()
是传递给 Row
构造函数的第二个属性。
现在您可以使用那个 Map
来构建树:
Map<Row,List<Row>> tree = list.stream().collect(Collectors.groupingBy(r->nodes.get(r.getParent())));
getParent()
是传递给 Row
构造函数的第一个属性。
这需要 Row
类正确覆盖 equals
和 hashCode
,这样两个 Row
实例将如果它们具有相同的名称,则被认为是相等的。
不过,您可能应该将根 Row
添加到您的输入 List
中。像这样的东西:
list.add(new Row(null, "-", "Root"));
编辑:
我用一个完整的 Row
类对其进行了测试(虽然我做了一些快捷方式),包括一个从根开始沿着每个级别的第一个子节点遍历树的示例:
class Row {
String name;
String parent;
Row (String parent,String name,String something) {
this.parent = parent;
this.name = name;
}
public String getParent () {return parent;}
public String getName () {return name;}
public int hashCode () {return name.hashCode ();}
public boolean equals (Object other) {
return ((Row) other).name.equals (name);
}
public String toString ()
{
return name;
}
public static void main (String[] args)
{
List<Row> list = new ArrayList<>();
list.add(new Row(null, "-", "Root"));
list.add(new Row("-", "A", "Root"));
list.add(new Row("A", "A1", "Alpha 1"));
list.add(new Row("A1", "A11", "Alpha 11"));
list.add(new Row("A", "A2", "Alpha 2"));
list.add(new Row("-", "B", "Root"));
list.add(new Row("B", "B1", "Bravo 1"));
list.add(new Row("B", "B2", "Bravo 2"));
Map<String,Row> nodes =
list.stream()
.collect(Collectors.toMap(Row::getName,Function.identity()));
Map<Row,List<Row>> tree =
list.stream()
.filter(r->r.getParent()!= null)
.collect(Collectors.groupingBy(r->nodes.get(r.getParent())));
System.out.println (tree);
Row root = nodes.get ("-");
while (root != null) {
System.out.print (root + " -> ");
List<Row> children = tree.get (root);
if (children != null && !children.isEmpty ()) {
root = children.get (0);
} else {
root = null;
}
}
System.out.println ();
}
}
输出:
树:
{A1=[A11], A=[A1, A2], B=[B1, B2], -=[A, B]}
遍历:
- -> A -> A1 -> A11 ->
关于java - 如何使用 Streams API 取消扁平化的层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54123464/