翻到祖师爷代码,发现树结构的数据是后端通过递归去生成的,效率非常低,请问有什么方法可以优化吗?
public List<Map> createGroupTreeNode() {
List<Map> childrenList = new ArrayList<Map>();
getChildList(0L,childrenList);
List<Map> treeList = new ArrayList<Map>();
Map map = new HashMap();
map.put("id", 0);
map.put("text","根节点");
map.put("isleaf", "0");
map.put("icon", "fa fa-folder");
Map subMap = new HashMap();
subMap.put("opened", true);
subMap.put("selected", true);
map.put("state", subMap);
map.put("children", childrenList);
treeList.add(map);
return treeList;
}
public List<Map> getChildList(Long id,List<Map> childrenList){
List<BaseGroup> childList = baseMapper.childListByParentId(id);
if(childList != null && childList.size() > 0){
List<Map> tempMap = new ArrayList<Map>();
for(int i = 0; i < childList.size(); i++){
List<Map> mylist = getChildList(childList.get(i).getId(),childrenList);
Map map = new HashMap();
if(mylist == null){
map.put("id", childList.get(i).getId());
map.put("text", childList.get(i).getNumber() + " - " + childList.get(i).getName());
map.put("isleaf", "1");
map.put("icon", "fa fa-folder");
Map subMap = new HashMap();
subMap.put("opened", false);
map.put("state", subMap);
tempMap.add(map);
}else{
map.put("id", childList.get(i).getId());
map.put("text", childList.get(i).getNumber() + " - " + childList.get(i).getName());
map.put("isleaf", "0");
map.put("icon", "fa fa-folder");
map.put("children", mylist);
Map subMap = new HashMap();
subMap.put("opened", false);
map.put("state", subMap);
tempMap.add(map);
}
if(id == 0){
childrenList.add(map);
}
}
return tempMap;
}
return null;
}
没看出哪里效率低
只是觉得这人应该去写php
如果 baseMapper
是数据库查询的话的确性能会很差,但跟递归没关系。
可以一次性查询出数据库记录,在内存中递归组合。如果数据库记录较多,可以加path
字段辅助查询收缩范围。
树状结构正确的处理方式是:使用缓存。
详细来说,初次使用的时候,用各种方法将树状结构生成出来,存为JSON格式的字符串。
后续直接读取这个JSON在前端渲染。
有人会说,如果数据更新了,那么这个缓存的就不能反映真实状况了。
所以,我们会先识别出影响树状结构源数据的所有入口,然后在入口触发这个JSON的更新。这样,就可以让JSON的更新不在每次访问的时候触发,可以减少频繁刷新导致的性能崩溃。
getChildList
的 childrenList
看起来是个输出参数,这里只有在 id == 0L
的时候会把元素加到 childrenList
中去。所以这个输入参数只在 id == 0L
的时候会使用。既然 getChildList
会把找到的列表返回出去,那完全不需要这个输出参数,在 createGroupTreeNode
里直接使用它的返回值就好。
public List<Map> createGroupTreeNode() {
List<Map> childrenList = getChildList(0L);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 不用初始化并作为输入参数传入,直接使用返回值就行
// ....
}
public List<Map> getChildList(Long id) {
// ^^^ 去掉 childrenList 参数
// ...
// if(id == 0){
// childrenList.add(map);
// }
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 不需要了
}
总体来说,关于递归,就只有这一点问题。
然后在里面,for 循环中的循环变量 i 只有一个作用,就是 childList.get(i)
,频繁的去使用 childList.get(i)
肯定不如缓存一个变量效率高,所以可以改为
for (int i = 0; i < childList.size(); i++) {
BaseGroup it = childList.get(i);
// 下面都用 it 代替 childList.get(i)
}
或者直接用增强 for 循环
for (BaseGroup it : childList) {
// ...
}
另外在 for 循环中的 if 分支,比较一下发现只有一丁点区别,就是在处理 isleaf
和 children
的时候,所以可以把其他 .put
都提取出来,只处理有差异的部分
Map map = new HashMap();
map.put("id", it.getId());
// ...
List<Map> mylist = getChildList(it.getId());
// ^^^ 这句话后移到使用它的地方,不需要提前去取
// ^^^^^^^^^^^^^^^^^^^^^^^^ 没要第二个参数了,前面说过
if (mylist == null) {
map.put("isleaf", "1");
}
else {
map.put("isleaf", "0");
map.put("children", mylist);
}
问题内容: 我有一个将位置链接在一起的数据库表;一个位置可以在一个位置,也可以在另一个位置内。 这是深入探讨MySQL / PHP的深度: 在给定父级位置的情况下,如何使用MySQL如何获得其所有后代位置,无论深度如何? 问题答案: mysql.com上有 一篇漂亮的文章 ,概述了管理分层数据的各种方法。我认为它为您的问题提供了完整的解决方案,并显示了各种不太简单但较快的方法(例如嵌套集)。
一、想要实现的效果 二、我的代码 public class People { } public static void main(String[] args) { 三、代码执行结果 四、解释 我递归用的少,用起来有点不达意。上面自己写的递归方法虽然能实现递归效果,但问题很大。 4.1、我的方法返回的只是命中项,而不是一个树的结构(除非第一层就命中了)。 4.2、返回的树里没有剔除未命中项。 上述两
本文向大家介绍数据结构 二叉树的递归与非递归,包括了数据结构 二叉树的递归与非递归的使用技巧和注意事项,需要的朋友参考一下 数据结构 二叉树的递归与非递归 实例代码: 先序遍历(递归法) 后序遍历 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
问题内容: 我的内存中有一个树结构,我想使用Django模板以HTML呈现。 将有一些对象是,并且是的列表。将在模板的内容中传递。 我发现这个的如何可能实现一个讨论,但海报表明,这在生产环境中可能不是很好。 有人知道更好的方法吗? 问题答案: 使用with模板标记,我可以做树/递归列表。 样例代码: 主模板:假设是树的一个或多个根的列表 tree_view_template.html呈现neste
我现在正在实现模拟N体问题的Barnes-Hut算法。我只想问关于建筑树的部分。 我做了两个函数来为它构建树。 我递归地构建树,并在构建时打印每个节点的数据,一切看起来都是正确的,但当程序返回到主函数时,只有树的根和根的子节点存储值。其他节点的值没有被存储,这很奇怪,因为我在递归过程中打印了它们,它们应该被存储。 这是经过修改的代码的一部分,我认为问题可能在哪里: 下面是函数set_root_an
我一直在用这个四叉树http://www.astroml.org/book_figures/chapter2/fig_quadtree_example.html 在一些数据上。但是我现在需要结果结构的嵌套表示。 其结构类似于: 这里的子元素是递归元素,它是一个列表,包括进一步的实例。最低深度没有子级(为0),是我想要访问的表示。因此,在这种情况下,我会访问数据 最终,我希望在最低级别的数据表示像: