1,编码实现
该方法来自一位国外大神的博客,通过`Map`以及Java对象在内存中的状态来实现树结构的组装,相比较使用递归的方法,该方法的时间复杂度和空间复杂度都会低一些。
如果要实现按原来顺序排列,可以使用`LinkedHashMap`
结构
// 方法体
private static void createTree(List<Node> nodes) {
System.err.println("开始");
Map<Integer, Node> mapTmp = new HashMap<>(nodes.size());
// put all node to map
for (Node node : nodes) {
mapTmp.put(node.getId(), node);
}
//loop and assign parent/child relationships
for (Node node : nodes) {
Integer parentId = node.getParentId();
// 如果是父级标签,则不做处理
if (parentId == null) {
continue;
}
Node parentNode = mapTmp.get(parentId);
if (parentNode == null) {
continue;
}
// 将值赋给父级的子集中
List<Node> children = parentNode.getChildren();
if (children == null) {
children = new ArrayList<>();
}
children.add(node);
parentNode.setChildren(children);
mapTmp.put(parentId, parentNode);
}
//extract root node
List<Node> trees = new ArrayList<>();
for (Node node :mapTmp.values()) {
if (node.getParentId() == null) {
trees.add(node);
}
}
System.err.println(trees);
System.err.println("结束");
}
DEMO
如下是代码实现及测试
class Node {
private String name;
private Integer id;
private Integer parentId;
private List<Node> children;
// getter and setter
}
public class CreateTree {
public static void main(String[] args) {
//Create a List of nodes
Node node1 = new Node("Five", 5, 4);
Node node2 = new Node("Four", 4, 2);
Node node3 = new Node("Two", 2, 1);
Node node4 = new Node("Three", 3, 2);
Node node5 = new Node("One", 1, null);
// root as parentId is null
List<Node> nodes = new ArrayList<>();
nodes.add(node1);
nodes.add(node2);
nodes.add(node3);
nodes.add(node4);
nodes.add(node5);
//convert to a tree
createTree(nodes);
}
private static void createTree(List<Node> nodes) {
System.err.println("开始");
Map<Integer, Node> mapTmp = new HashMap<>(nodes.size());
// put all node to map
for (Node node : nodes) {
mapTmp.put(node.getId(), node);
}
//loop and assign parent/child relationships
for (Node node : nodes) {
Integer parentId = node.getParentId();
if (parentId == null) {
continue;
}
Node parentNode = mapTmp.get(parentId);
if (parentNode == null) {
continue;
}
List<Node> children = parentNode.getChildren();
if (children == null) {
children = new ArrayList<>();
}
children.add(node);
parentNode.setChildren(children);
mapTmp.put(parentId, parentNode);
}
//extract root node
List<Node> trees = new ArrayList<>();
for (Node node :mapTmp.values()) {
if (node.getParentId() == null) {
trees.add(node);
}
}
System.err.println(trees);
System.err.println("结束");
}
}
2,原理解析
map中保存的value为对象的指针,而对象保存在堆内存中;当给该对象的children赋值的时候,也是将`children对象`的指针赋值给当前对象;所以程序中看似是对单个对象进行操作,实际上对象本身的结构已经发生了较大的改变。
所以实际原理就是通过内存和指针的运用来实现树结构的组装。
另一方面HashMap的hash算法的使用是比循环要节省性能和时间的;