网站首页 > java教程 正文
背景
最近项目上有一个需求,在网页上的nav菜单需要展示成树形结构,还有很多数据也要展示树形结构,所以说需要封装一个公共方法来将对象List转为Tree树形数据结构。
挖坑
在第一次做的时候给自己挖了一个大坑,请先看代码
public final List<Map<String, Object>> listToTree(String parentId, List<TaskEntity> list){
List<Map<String, Object>> maps = new ArrayList<>();
for (TaskEntity task : list){
if (StringUtils.isBlank(parentId) && StringUtils.isBlank(task.getParentId())){
Map<String, Object> map = JSON.parseObject(JSON.toJSONString(task), Map.class);
map.put("children", listToTree(task.getId(), list));
maps.add(map);
} else if (StringUtils.isNotBlank(parentId) && StringUtils.isNotBlank(task.getParentId()) && parentId.equals(task.getParentId())){
Map<String, Object> map = JSON.parseObject(JSON.toJSONString(task), Map.class);
map.put("children", listToTree(task.getId(), list));
maps.add(map);
}
}
return maps;
}
但是这种方法必须要传一个顶级数据的parentId,一般来说,最上级的数据parentId为null,直接调用这个方法传入parentId为null就可以,但是假如说我查询出一个list,但是这个list的没有最上级对象呢,那就不确定list中的哪个对象是最顶级,那这个parentId参数传什么呢?
填坑
首先讲一下思路,首先坑定是查出来一个list对象集合,然后找出list中最顶级的对象list,然后循环顶级list,然后找到list中含有parentId为当前循环到的顶级对象id的下一级对象List,加到当前循环的顶级对象的“children”属性中,children也是一个list集合,然后递归循环,直到取出所有数据转为Tree,下面看代码。
- 对象List转为Tree树形结构的方法
/**
* 对象List转为Tree树形结构
* @param entityList 数据List
* @param parentFileName 用作上级ID的属性名
* @return
*/
public final List<Map<String, Object>> listToTree(List<T> entityList, String parentFileName){
List<Map<String, Object>> mapList = new ArrayList<>();
List<T> topList = getTopList(entityList, parentFileName);
topList.forEach(entity -> {
Map<String, Object> map = JSON.parseObject(JSON.toJSONString(entity, SerializerFeature.WriteMapNullValue), Map.class);
if (!map.containsKey(parentFileName)) throw new NullPointerException("父级ID字段:" + parentFileName + " 不存在于对象中");
map.put("children", getChildren(entity, entityList, parentFileName));
mapList.add(map);
});
return mapList;
}
- 得到最顶级的数据List
/**
* 得到最顶级的数据List
* @param entityList
* @param parentFileName
* @return
*/
private final List<T> getTopList(List<T> entityList, String parentFileName){
List<T> topList = new ArrayList<>();
entityList.forEach(topEntity -> {
AtomicBoolean isParent = new AtomicBoolean(true);
Map<String, Object> topMap = JSON.parseObject(JSON.toJSONString(topEntity, SerializerFeature.WriteMapNullValue), Map.class);
entityList.forEach(entity -> {
if (!topMap.containsKey(parentFileName)) throw new NullPointerException("父级ID字段:" + parentFileName + " 不存在于对象中");
if (entity.getId().equals(topMap.get(parentFileName))){
isParent.set(false);
}
});
if (isParent.get()){
topList.add(topEntity);
}
});
return topList;
}
- 递归获取子级List,这里是个递归方法(方法中会调用这个方法本身)
private final List<Map<String, Object>> getChildren(T parent, List<T> entityList, String parentFileName){
List<Map<String, Object>> mapList = new ArrayList<>();
entityList.forEach(item -> {
Map<String, Object> map = JSON.parseObject(JSON.toJSONString(item, SerializerFeature.WriteMapNullValue), Map.class);
if (!map.containsKey(parentFileName)) throw new NullPointerException("父级ID字段:" + parentFileName + " 不存在于对象中");
if (parent.getId().equals(map.get(parentFileName))){
map.put("children", getChildren(item, entityList, parentFileName));
mapList.add(map);
}
});
return mapList;
}
总结
- 具体实现思路就是:
- 得到最顶级对象List;
- 循环最顶级List并调用递归方法;
- 递归方法中在调用本身;
- 最后获得一个树形的Map集合。
注意
以上方法是封装在通用CRUD的service层的,项目中用到了MybatisPlus,然后继承MybatisPlus中的通用CRUD二次封装了一下,代码中的“T”为对象中的泛型,所以以上代码只是给大家提供一下思路,防止自己挖坑。方法可能无法直接使用到你的项目中,还是需要你自己看下,捋一捋思路的。祝你好运吧!!!
猜你喜欢
- 2024-10-03 SpringBoot中如何根据JSON数据生成一个动态对象?
- 2024-10-03 边玩手机边学Java----Java基础之Map
- 2024-10-03 Java Stream API:优雅地操作Map(java map stream filter)
- 2024-10-03 聊聊Mybatis的初始化之Mapper.xml映射文件的解析
- 2024-10-03 MapStruct 使用教程, 万字详解(mapstruct enum)
- 2024-10-03 看似简单,在JAVA中如何将一个Object转换成Array
- 2024-10-03 java8函数式Map操作也太强大了吧,1次就帮我省了10多行代码
- 2024-10-03 map的一个骚操作!你学废了么?#互联网
- 2024-10-03 轻松搞定!用JavaScript将列表转换为Map
- 2024-10-03 告别 BeanUtils,拥抱 MapStruct:高效 Java 对象映射的经典之选
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)