java父子节点parentid树形结构数据的规整
作者:孺子牛牛
这篇文章主要介绍了java父子节点parentid树形结构数据的规整,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
java父子节点parentid树形结构数据
这几天写一个父子节点的数据规整,在网上找了一些方法,都太繁琐,自己写了一个,感觉比较简单
先说一下原理
第一,我们从数据库中将需要的数据查询出来,得到一个Object集合的list
第二,定义一个map,key为id,value为Object,这个的目的是为了方便后面的查找
第三,遍历第一步中查询到的数据集合list,取出Object中的parentid,根据parentid从第二步map中取出它的父节点,将其放入到父节点中去
第四,删除map中父节点parentid不为空的数据,这样我们的数据结构就组成了。
这里主要使用了java在参数传递时,如果参数是一个object时,那么它传递的是引用这么一个思想来进行实现,贴出代码供大家参考
public class Test {
public List<Goal> test(List<Goal> listGoal) {
Map<Integer, Goal> goalMap = new HashMap<Integer, Goal>();
for (Goal g : listGoal) {
int id = g.getId();
goalMap.put(id, g);
}
for (Goal g : listGoal) {
int pid = g.getParentId();
if (pid != 0) {
Goal tempGoal = goalMap.get(pid);
List<Goal> tempListGoal = tempGoal.getListGoal();
if (tempListGoal == null) {
tempListGoal = new ArrayList<Goal>();
}
tempListGoal.add(g);
tempGoal.setListGoal(tempListGoal);
}
}
List<Integer> list = new ArrayList<Integer>();
for (Integer k : goalMap.keySet()) {
Goal tempGoal = goalMap.get(k);
if (tempGoal.getParentId() != 0) {
list.add(k);
}
}
for (int i : list) {
goalMap.remove(i);
}
return new ArrayList<Goal>(goalMap.values());
}
public static void main(String[] args) {
List<Goal> listGoal = new ArrayList<Goal>();
Goal g1 = new Goal();
g1.setId(1);
g1.setParentId(0);
g1.setGoalName("g1");
Goal g2 = new Goal();
g2.setId(2);
g2.setParentId(1);
g2.setGoalName("g2");
Goal g3 = new Goal();
g3.setId(3);
g3.setParentId(2);
g3.setGoalName("g3");
Goal g4 = new Goal();
g4.setId(4);
g4.setParentId(2);
g4.setGoalName("g4");
Goal g5 = new Goal();
g5.setId(5);
g5.setParentId(3);
g5.setGoalName("g5");
Goal g6 = new Goal();
g6.setId(6);
g6.setParentId(0);
g6.setGoalName("g6");
Goal g7 = new Goal();
g7.setId(7);
g7.setParentId(3);
g7.setGoalName("g7");
Goal g8 = new Goal();
g8.setId(8);
g8.setParentId(7);
g8.setGoalName("g8");
Goal g9 = new Goal();
g9.setId(9);
g9.setParentId(7);
g9.setGoalName("g9");
Goal g10 = new Goal();
g10.setId(10);
g10.setParentId(4);
g10.setGoalName("g10");
Goal g11 = new Goal();
g11.setId(11);
g11.setParentId(10);
g11.setGoalName("g1");
Goal g12 = new Goal();
g12.setId(12);
g12.setParentId(7);
g12.setGoalName("g12");
Goal g13 = new Goal();
g13.setId(13);
g13.setParentId(0);
g13.setGoalName("g13");
listGoal.add(g1);
listGoal.add(g2);
listGoal.add(g3);
listGoal.add(g4);
listGoal.add(g5);
listGoal.add(g6);
listGoal.add(g7);
listGoal.add(g8);
listGoal.add(g9);
listGoal.add(g10);
listGoal.add(g11);
listGoal.add(g12);
listGoal.add(g13);
Test t = new Test();
List<Goal> listT = t.test(listGoal);
System.out.println(listT);
}java将有父子关系的数据转换成树形结构数据
数据库父子结构数据设计
大部分采用 parentId的形式来存储父id,并且只存储父id,祖父Id不存储。也可以添加存储层级级别或者层级关系等字段。
CREATE TABLE `t_resource` ( `id` varchar(255) NOT NULL COMMENT '主键', `parent_id` varchar(255) DEFAULT NULL COMMENT '父ID', `name` varchar(255) DEFAULT NULL COMMENT '名称', `url` varchar(255) DEFAULT NULL COMMENT '资源url', `level` varchar(255) DEFAULT NULL COMMENT '层级级别', `decode` varchar(255) DEFAULT NULL COMMENT '层级ID的关系,用”_“分割', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

将有父子关系的数据转换成树形结构数据
mapper层获取数据库数据和 controller层处理很简单,将有父子关系的数据转换成树形结构数据交给 service层处理。
@PostMapping("/getMuneTree")
@ResponseBody
public ResponseEntity<Map<String, Object>> getMuneTree(){
Map<String, Object> map = new HashMap<>();
map.put("menuList", resourceDOService.getMuneTree());
return ResponseEntity.ok(map);
} 
1、方式一:递归:从树的最顶级获取子级,然后子级获取其子级。
返回时,需要哪些字段值就添加哪些字段值到 map中。结果图如上
/**
* 将有父子关系的数据转换成树形结构数据
*
* @return 最终的树状结构的集合数据
*/
@Override
public List<Map<String, Object>> getMuneTree() {
// 获取数据库中带有有父子关系的数据
List<ResourceDO> data = resourceDOMapper.selectAll();
//创建一个List集合来存放最终的树状结构数据
List<Map<String, Object>> menuList = new ArrayList<>();
// 先存入最顶级的树(0代表没有父级,即最顶级),然后通过最顶级的id递归获取子级
for (ResourceDO entity : data) {
Map<String, Object> map = new HashMap<>();
if ("0".equals(entity.getParentId())) {
map.put("id", entity.getId());
map.put("parentId", entity.getParentId());
map.put("name", entity.getName());
map.put("children", getChildren(data, entity.getId()));
menuList.add(map);
}
}
return menuList;
}
/**
* 递归处理:通过id获取子级,查询子级下的子级
*
* @param data 数据库的原始数据
* @param id 主id
* @return 该id下得子级
*/
public List<Map<String, Object>> getChildren(List<ResourceDO> data, String id) {
List<Map<String, Object>> list = new ArrayList<>();
if (data == null || data.size() == 0 || id == null) {
return list;
}
for (ResourceDO entity : data) {
Map<String, Object> map = new HashMap<>();
//如果本级id与数据的父id相同,就说明是子父级关系
if (id.equals(entity.getParentId())) {
map.put("id", entity.getId());
map.put("parentId", entity.getParentId());
map.put("name", entity.getName());
//查询子级下的子级
map.put("children", getChildren(data, entity.getId()));
list.add(map);
}
}
return list;
}2、方式二:组装带有children关联性的对象
在实体列中定义一个 children集合:
private List<ResourceDO> children = new ArrayList<>();
返回的是实体类对象的所有值,这里操作的都是集合存储对象的引用
/**
* 将有父子关系的数据转换成树形结构数据
*
* @return 最终的树状结构的集合数据
*/
@Override
public List<ResourceDO> getMuneTree2() {
// 获取数据库中带有有父子关系的数据
List<ResourceDO> data = resourceDOMapper.selectAll();
// 复制data数据
List<ResourceDO> menuList = new ArrayList<>(data);
// 遍历两次data来组装带有children关联性的对象,如果找到子级就删除menuList的数据
for (ResourceDO entity : data) {
for (ResourceDO entity2 : data) {
//如果本级id与数据的父id相同,就说明是子父级关系
if (entity.getId().equals(entity2.getParentId())) {
entity.getChildren().add(entity2);
menuList.remove(entity2);
}
}
}
return menuList;
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
