列表转树 ,数据结构处理,list ->tree
上一篇随笔,说了一下列表转树的操作,但是很有局限性,例如,id必须是自增长,必须现有父id才能有子id,这样就会有一些局限性,特别是自增长,因为不能排序,所以就无法处理。
今天又遇到这个列表转树结构处理,起因是因为测试提了一个bug,一个方法2.5s的相应时间,测试人员强烈要求优化,没办法优化吧。
bug提到我这边,我开始接管这一块内容。
先大致测试了分析一下,大概sql执行1.8s左右,列表转树0.5s左右,看到这些,其他的时间耗费就先不用管了,这两块是大头,搞定这两块就准备收工。
1:sql优化,之前写的sql实在是烂,不想多说,优化之后效率提高,至于提高多少,还要精确测试,这个不再讨论了。
2:列表转树:
之前的代码采用多层循环,和树的层级成方次的关系,O^N的时间复杂度。
不能忍,坚决改,必须采用时间换空间的方法。
代码如下:
public static List listToTree(List<JSONObject> list ){ //空间换时间,所需要的空间,为了防止那些没有根节点的错误节点存在,造成map扩容造成的性能损耗,直接左移一位处理,如果可以保证没有错误的节点或不在意这个优化,可以直接使用list.size() HashMap<Object, JSONObject> tempMap = new HashMap<>(list.size()<<1); //最顶层的根节点 List rootList = new ArrayList(); for (JSONObject node: list) { //当前节点名称 Object id = node.get("deptCode"); //父节点名称 Object parentid = node.get("parentCode"); //处理当前节点,可能先处理父节点时,已经把该节点挂载子节点了,如果没有的话就新建一个 JSONObject packageBody = tempMap.getOrDefault(id,new JSONObject()); //把之前添加的children信息拿过来,挂载到现在的node下。putIfAbsent node.putIfAbsent("children",packageBody.getOrDefault("children",new ArrayList<>())); tempMap.put(id,node); //处理顶级节点,parentid为null的情况下,为顶级节点 if(ObjectUtil.isNull(parentid)){ rootList.add(node); }else{ //把当前节点挂到父节点下 //获取父节点,父节点不存在就先初始化一个 JSONObject parent = tempMap.getOrDefault(parentid,new JSONObject()); //父节点为空情况 //1 还没处理到:创建一个, 2 没有父节点的子节点,坏的数据,丢进去,最后不会被挂到根节点下 ArrayList children = (ArrayList)parent.getOrDefault("children",new ArrayList()); parent.put("children",children); //把当前节点挂载到父节点下 children.add(node); //把父节点也挂到map中放到节点下 tempMap.put(parentid,parent); } } return rootList; }
测试代码如下:
public static void main(String[] args){
List<JSONObject> treeNodeList = new ArrayList<>();
JSONObject treeNode1 = JSON.parseObject("{'deptCode':'1','parentCode':null,'ms':'ces','name':'ss'}");
JSONObject treeNode2 =JSON.parseObject("{'deptCode':'2','parentCode':null,'ms':'订单','name':'ss'}");
JSONObject treeNode3 =JSON.parseObject("{'deptCode':'3','parentCode':'1','ms':'预约','name':'ss'}");
JSONObject treeNode4 =JSON.parseObject("{'deptCode':'4','parentCode':'2','ms':'捐献','name':'ss'}");
JSONObject treeNode5 =JSON.parseObject("{'deptCode':'5','parentCode':'4','ms':'我的订单','name':'ss'}");
JSONObject treeNode6 =JSON.parseObject("{'deptCode':'6','parentCode':'4','ms':'个人中心','name':'ss'}");
JSONObject treeNode7 = JSON.parseObject("{'deptCode':'7','parentCode':'6','ms':'个人中心2','name':'ss'}");
JSONObject treeNode8 = JSON.parseObject("{'deptCode':'8','parentCode':'99','ms':'个人中心3','name':'ss'}");
treeNodeList.add(treeNode1);
treeNodeList.add(treeNode6);
treeNodeList.add(treeNode5);
treeNodeList.add(treeNode3);
treeNodeList.add(treeNode4);
treeNodeList.add(treeNode2);
treeNodeList.add(treeNode7);
treeNodeList.add(treeNode8);
System.out.print(MasterTreeUtil.listToTree(treeNodeList));
}
打印的结果格式化之后:

截图没截完,就这样吧。
说明:此方法为扩充上次list转树,parentid不能进行排序做的优化方案,一次排序处理即可。
代码中的deptCode,以及parentCode是排序的关键字,每个项目不同,因为这个是我根据自己已经完成的方案改写,所以就直接硬编码使用了。不要在意这些细节~~~
如果感觉那里不明白,可以看上一篇的理论和说明,这里不再多说了。
最后说一下,最后在我本机测试的结果,该方案1400条数据,三层结构,消耗时间是20ms左右,相比之前优化了25倍。(当然,是我自己的代码,不是这个示例,这个示例还没测试效果,但是大概也不差多少)
最后说一下,看代码里面的,循环里面的 new 对象的处理,这个很难看,因为是示例代码我就不做处理了,你们可以优化一下。^.^ 我只做列表转树······

浙公网安备 33010602011771号