堆栈 and 递归 获取无限极树形菜单

来源:互联网 发布:交换机端口号怎么看 编辑:程序博客网 时间:2024/05/24 03:08

一直对树形菜单的加载效率忧心,经过别人提点,获知可以通过堆栈的方式来优化菜单的获取效率。

因此,小研究了一下之后,发现堆栈的效率确实提高的不是一点两点。

下面将分享一下测试代码。

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

各类名称可能取得不是很贴切,凑合着看吧。测试多次之后,堆栈的效率,可以的。递归,确实是相当效率慢啊!