假设我们有一个含id和parentId的对象列表,如下所示:
List<Node> nodeList = Arrays.asList(
new Node(1, 0, "Node 1"),
new Node(2, 1, "Node 1.1"),
new Node(3, 1, "Node 1.2"),
new Node(4, 2, "Node 1.1.1"),
new Node(5, 2, "Node 1.1.2"),
new Node(6, 3, "Node 1.2.1"),
new Node(7, 3, "Node 1.2.2"),
new Node(8, 0, "Node 2"),
new Node(9, 8, "Node 2.1"),
new Node(10, 8, "Node 2.2"),
new Node(11, 9, "Node 2.1.1"),
new Node(12, 9, "Node 2.1.2"),
new Node(13, 10, "Node 2.2.1")
);
,id和parentId分别表示节点的唯一标识和父节点的标识,0表示根节点。
我们可以使用Java 8的Stream API来生成树形结构。首,我们将节点列表按parentId进行分组:
Map<Integer, List<Node>> nodeMap = nodeList.stream()
.collect(Collectors.groupingBy(Node::getParentId));
这样,我们就得到了一个Map,每个键值对表示一个父节点和它的所有子节点。接下来,我们可以递归地构建树形结构:
List<Node> treeList = buildTree(nodeMap, 0);
private static List<Node> buildTree(Map<Integer, List<Node>> nodeMap, int parentId) {
List<Node> nodeList = nodeMap.get(parentId);
if (nodeList == null) {
return Collections.emptyList();
}
return nodeList.stream()
.peek(node -> node.setChildren(buildTree(nodeMap, node.getId())))
.collect(Collectors.toList());
}
这里,我们定义了一个buildTree方法,它接收一个节点Map和一个父节点id,返回以该父节点为根节点的树形结构。首,我们从节点Map中获取以该父节点为父节点的所有子节点列表。如果该列表为空,说明该节点没有子节点,直接返回一个空列表。否则,我们使用Stream API递归地构建子树,并将设置为该节点的子节点列表。最后,我们将所有子节点收集到一个列表中,并返回。
这样,我们就可以使用Java 8的Stream API生成树形结构了。完整的代码如下所示:
import java.util.*;
import java.util.stream.Collectors;
public class TreeBuilder {
public static void main(String[] args) {
List<Node> nodeList = Arrays.asList(
new Node(1, 0, "Node 1"),
new Node(2, 1, "Node 1.1"),
new Node(3, 1, "Node 1.2"),
new Node(4, 2, "Node 1.1.1"),
new Node(5, 2, "Node 1.1.2"),
new Node(6, 3, "Node 1.2.1"),
new Node(7, 3, "Node 1.2.2"),
new Node(8, 0, "Node 2"),
new Node(9, 8, "Node 2.1"),
new Node(10, 8, "Node 2.2"),
new Node(11, 9, "Node 2.1.1"),
new Node(12, 9, "Node 2.1.2"),
new Node(13, 10, "Node 2.2.1")
);
System.out.println(treeList);
}
private static List<Node> buildTree(Map<Integer, List<Node>> nodeMap, int parentId) {
List<Node> nodeList = nodeMap.get(parentId);
if (nodeList == null) {
return Collections.emptyList();
}
return nodeList.stream()
.peek(node -> node.setChildren(buildTree(nodeMap, node.getId())))
.collect(Collectors.toList());
}
}
class Node {
private int id;
private int parentId;
private String name;
private List<Node> children = new ArrayList<>();
public Node(int id, int parentId, String name) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
public int getId() {
return id;
}
public int getParentId() {
return parentId;
}
public String getName() {
return name;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
@Override
public String toString() {
return "Node{" +
"id=" + id +
", parentId=" + parentId +
", name='" + name + '\'' +
", children=" + children +
'}';
}
}
输出结果为:
[Node{id=1, parentId=0, name='Node 1', children=[Node{id=2, parentId=1, name='Node 1.1', children=[Node{id=4, parentId=2, name='Node 1.1.1', children=[]}, Node{id=5, parentId=2, name='Node 1.1.2', children=[]}]}, Node{id=3, parentId=1, name='Node 1.2', children=[Node{id=6, parentId=3, name='Node 1.2.1', children=[]}, Node{id=7, parentId=3, name='Node 1.2.2', children=[]}]}]}, Node{id=8, parentId=0, name='Node 2', children=[Node{id=9, parentId=8, name='Node 2.1', children=[Node{id=11, parentId=9, name='Node 2.1.1', children=[]}, Node{id=12, parentId=9, name='Node 2.1.2', children=[]}]}, Node{id=10, parentId=8, name='Node 2.2', children=[Node{id=13, parentId=10, name='Node 2.2.1', children=[]}]}]}]