一直对树形菜单的加载效率忧心,经过别人提点,获知可以通过堆栈的方式来优化菜单的获取效率。
因此,小研究了一下之后,发现堆栈的效率确实提高的不是一点两点。
下面将分享一下测试代码。
1、在同一个java文件中,声明一个非public的class,TreeNode
class TreeNode {
private String id;
private String pid;
private List<TreeNode> childNode;
public TreeNode(String id) {
this.id = id;
this.pid = "-1";
}
public TreeNode(String id, String pid) {
this.id = id;
this.pid = pid;
}
public List<TreeNode> getChildNode() {
return childNode;
}
public void setChildNode(List<TreeNode> childNode) {
this.childNode = childNode;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
2、public的class StackTree
public class StackTree {
public TreeNode recursiveTree(TreeNode rootNode) {
List<TreeNode> childNodes = getChildren(rootNode);
if (CollectionUtils.isNotEmpty(childNodes)) {
for (TreeNode childNode : childNodes) {
recursiveTree(childNode);
}
rootNode.setChildNode(childNodes);
}
return rootNode;
}
public TreeNode breadthTree(TreeNode rootNode) {
Deque<TreeNode> nodeDeque = new ArrayDeque<>();
TreeNode node = rootNode;
nodeDeque.add(node);
while (!nodeDeque.isEmpty()) {
node = nodeDeque.pop();
// 获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点
List<TreeNode> children = getChildren(node);
if (children != null && !children.isEmpty()) {
node.setChildNode(children);
for (TreeNode child : children) {
nodeDeque.add(child);
}
}
}
return rootNode;
}
public List<TreeNode> getChildren(TreeNode node) {
List<TreeNode> childNodes = new ArrayList<>();
if (node.getId().length() < 3) {
for (int i = 0; i < 5; i++) {
String childNodeId = node.getId() + "" + (i + 1);
TreeNode childNode = new TreeNode(childNodeId, node.getId());
childNodes.add(childNode);
}
}
return childNodes;
}
public static void main(String[] args) {
StackTree tree = new StackTree();
TreeNode rootNode = new TreeNode("11", "1");
System.out.println("--------------------------------");
Date stackStart = new Date();
rootNode = tree.breadthTree(rootNode);
Date stackEnd = new Date();
System.out.println(rootNode);
System.out.println("堆栈耗时:" + (stackEnd.getTime() - stackStart.getTime()));
rootNode = new TreeNode("11", "1");
System.out.println("--------------------------------");
Date recursiveStart = new Date();
tree.recursiveTree(rootNode);
Date recursiveEnd = new Date();
System.out.println(rootNode);
System.out.println("递归耗时:" + (recursiveEnd.getTime() - recursiveStart.getTime()));
}
}
以上可以看见,recursiveTree是递归获取菜单,breadthTree是堆栈获取菜单的方法。
运行一下,可以看到我们main方法的输出,结果是一样的,但耗时不一样。
--------------------------------
{"childNode":[{"id":"111","pid":"11"},{"id":"112","pid":"11"},{"id":"113","pid":"11"},{"id":"114","pid":"11"},{"id":"115","pid":"11"}],"id":"11","pid":"1"}
堆栈耗时:1
--------------------------------
{"childNode":[{"id":"111","pid":"11"},{"id":"112","pid":"11"},{"id":"113","pid":"11"},{"id":"114","pid":"11"},{"id":"115","pid":"11"}],"id":"11","pid":"1"}
递归耗时:10
各类名称可能取得不是很贴切,凑合着看吧。测试多次之后,堆栈的效率,可以的。递归,确实是相当效率慢啊!