不使用递归,如何构造树结构

原理很简单,利用对象引用特性。

科普一下知识点:

浅拷贝:
浅拷贝又称为浅复制,浅克隆,浅拷贝是指拷贝时只拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用所指向的对象,拷贝出来的对象的所有变量的值都含有与原来对象相同的值,而所有对其他对象的引用都指向原来的对象,简单地说,浅拷贝只拷贝对象不拷贝引用。

深拷贝:
深拷贝又称为深复制,深克隆,深拷贝不仅拷贝对象本身,而且还拷贝对象包含的引用所指向的对象,拷贝出来的对象的所有变量(不包含那些引用其他对象的变量)的值都含有与原来对象的相同的值,那些引用其他对象的变量将指向新复制出来的新对象,而不指向原来的对象,简单地说,深拷贝不仅拷贝对象,而且还拷贝对象包含的引用所指向的对象。

思路:

在构建树形结构时,我们最常用方法是使用递归算法进行处理,让程序按照我们的想法一步一步的向下查找子节点,这个过程是程序员通过代码控制的;

参考对象引用的特性,这个过程其实完全可以利用引用特性自动执行;

进入正题:

第一步:判断实体中包含 id parentId childList这三个构建一颗树的必备属性;

第二步:查找到每一列数据的下一级元素;

第三步:记录所有的 id,用于筛选出来第一级的节点,一个简单的思路,如果 parentId  不存在于 ids数组中,那么当前节点一定是一级节点;

第四步:将一级节点加入新数组,并返回;

直接上代码:

 1 public <E extends Object> List<E> tree(List<E> e) {  2         List<E> result = new ArrayList<>();  3         List<Long> ids = new ArrayList<>();  4         for (E e1 : e) {  5             Method setChildList = e1.getClass().getMethod("setChildList",List.class);  6             if(ObjectUtils.isEmpty(setChildList)) continue;  7             Method getId = e1.getClass().getMethod("getId");  8             if(ObjectUtils.isEmpty(getId)) continue;  9             long id = (long) getId.invoke(e1); 10             if(ObjectUtils.isEmpty(id)) continue; 11             Method getParentId = e1.getClass().getMethod("getParentId"); 12             if(ObjectUtils.isEmpty(getParentId)) continue; 13             long parentId = (long) getParentId.invoke(e1); 14             if(ObjectUtils.isEmpty(parentId)) continue; 15             ids.add(id); 16             List<E> es = e.stream().filter(p -> { 17                 try { 18                     Method pk = p.getClass().getMethod("getParentId"); 19                     if (ObjectUtils.isEmpty(pk)) return false; 20                     long pv = (long) pk.invoke(p); 21                     if (ObjectUtils.isEmpty(pv)) return false; 22                     return pv == id; 23                 } catch (Throwable ex) { 24                     return false; 25                 } 26             }).collect(Collectors.toList()); 27             if(!ObjectUtils.isEmpty(es)) setChildList.invoke(e1,es); 28         } 29         for (E e1 : e) { 30             Method getParentId = e1.getClass().getMethod("getParentId"); 31             if(ObjectUtils.isEmpty(getParentId)) continue; 32             long parentId = (long) getParentId.invoke(e1); 33             if(ObjectUtils.isEmpty(parentId)) continue; 34             if(!ids.contains(parentId)) result.add(e1); 35         } 36  37         return result; 38     }

 

发表评论

评论已关闭。

相关文章