1、实体类结构
public class ItopsAssetType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键id */
private Long assetTypeId;
private String assetTypeName;
/** 父id */
@Excel(name = "父id")
private Long parentId;
private List<ItopsAssetType> assetTypes;//父下面的所有儿子集合
}
2、数据库结构
3、组装成树的工具类*
//获取资产类型树结构展示
@Override
public List<ItopsAssetType> getAssetTypeTree() {
List<ItopsAssetType> list = itopsAssetTypeMapper.getAssetTypeAll();//查询数据库所有
List<ItopsAssetType> itopsAssetTypes = parentAndChildren(list);
return itopsAssetTypes;
}
private List<ItopsAssetType> parentAndChildren(List<ItopsAssetType> list){
//最顶层根节点
List<ItopsAssetType>rootList = new ArrayList<>();
//非最顶层根节点
List<ItopsAssetType>bodyList = new ArrayList<>();
for (ItopsAssetType ebmMonographType : list) {
//将最外层数据拿出来
if (ebmMonographType.getParentId() == 0){
rootList.add(ebmMonographType);
}else{
//将不是最外层数据拿出来
bodyList.add(ebmMonographType);
}
}
return getTree(rootList,bodyList);
}
public List<ItopsAssetType> getTree(List<ItopsAssetType>rootList, List<ItopsAssetType>bodyList){
if (bodyList != null && !bodyList.isEmpty()){
//声明一个map,用来过滤已操作过的数据
Map<Long,Long> map = new HashMap<>(bodyList.size());
rootList.forEach(parent->getChild(parent,bodyList,map));
return rootList;
}else{
return rootList;
}
}
private void getChild(ItopsAssetType parent,List<ItopsAssetType>bodyList, Map<Long,Long> map){
List<ItopsAssetType>childList = new ArrayList<>();
//当前是stream流写法
// bodyList.stream().filter(c->!map.containsKey(c.getAssetTypeId()))
// .filter(c->c.getParentId().equals(parent.getAssetTypeId()))
// .forEach(c->{
// map.put(c.getAssetTypeId(),c.getParentId());
// getChild(c,bodyList,map);
// childList.add(c);
// });
//分别一层一层的取出下一个数据,然后和所有子数据进行比较,满足条件则放入自己的集合中
for (ItopsAssetType itopsAssetType : bodyList) {
if (!map.containsKey(itopsAssetType.getAssetTypeId())){//map不包含主键id
if (itopsAssetType.getParentId().equals(parent.getAssetTypeId())){//下级的父id = 上一层的id
map.put(itopsAssetType.getAssetTypeId(),itopsAssetType.getParentId());
getChild(itopsAssetType,bodyList,map);
childList.add(itopsAssetType);
}
}
}
parent.setAssetTypes(childList);
}
2、第二种方式
//1、返回的实体类
public class TreeSelect implements Serializable
{
private static final long serialVersionUID = 1L;
/** 节点ID */
private Long id;
/** 节点名称 */
private String label;
/** 子节点 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeSelect> children;
}
public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts){
List<SysDept> deptTrees = buildDeptTree(depts);//depts:树形表的所有数据
return deptTrees;//返回这个也可以,只不过数据太多
return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
}
@Override
public List<SysDept> buildDeptTree(List<SysDept> depts) {
List<SysDept> returnList = new ArrayList<>();
List<Long> tempList = new ArrayList<>();
for (SysDept dept : depts) {
tempList.add(dept.getDeptId());
}
for (SysDept dept : depts) {
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(dept.getParentId())) {
recursionFn(depts, dept);
returnList.add(dept);
}
}
if (returnList.isEmpty()) {
returnList = depts;
}
return returnList;
}
/**
* 递归列表
* t 上层节点
* list:所有数据
*/
private void recursionFn(List<SysDept> list, SysDept t) {
// 得到子节点列表
List<SysDept> childList = getChildList(list, t);
t.setChildren(childList);//将当前子集放入到当前的对象集合中
for (SysDept tChild : childList) {
if (hasChild(list, tChild)) {//当前对象中有子数据
recursionFn(list, tChild);
}
}
}
/**
* 判断是否有子节点
*/
private boolean hasChild(List<SysDept> list, SysDept t) {
return getChildList(list, t).size() > 0 ? true : false;
}
/**
* 得到子节点列表
*/
private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
List<SysDept> tlist = new ArrayList<>();
Iterator<SysDept> it = list.iterator();
while (it.hasNext()) {
SysDept n = (SysDept) it.next();
if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
tlist.add(n);
}
}
return tlist;
}