java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java父子节点parentid树形结构数据

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;
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文