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; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。