最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java父子節(jié)點(diǎn)parentid樹形結(jié)構(gòu)數(shù)據(jù)的規(guī)整

 更新時(shí)間:2023年07月21日 16:20:27   作者:孺子牛牛  
這篇文章主要介紹了java父子節(jié)點(diǎn)parentid樹形結(jié)構(gòu)數(shù)據(jù)的規(guī)整,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

java父子節(jié)點(diǎn)parentid樹形結(jié)構(gòu)數(shù)據(jù)

這幾天寫一個(gè)父子節(jié)點(diǎn)的數(shù)據(jù)規(guī)整,在網(wǎng)上找了一些方法,都太繁瑣,自己寫了一個(gè),感覺比較簡單

先說一下原理

第一,我們從數(shù)據(jù)庫中將需要的數(shù)據(jù)查詢出來,得到一個(gè)Object集合的list

第二,定義一個(gè)map,key為id,value為Object,這個(gè)的目的是為了方便后面的查找

第三,遍歷第一步中查詢到的數(shù)據(jù)集合list,取出Object中的parentid,根據(jù)parentid從第二步map中取出它的父節(jié)點(diǎn),將其放入到父節(jié)點(diǎn)中去

第四,刪除map中父節(jié)點(diǎn)parentid不為空的數(shù)據(jù),這樣我們的數(shù)據(jù)結(jié)構(gòu)就組成了。

這里主要使用了java在參數(shù)傳遞時(shí),如果參數(shù)是一個(gè)object時(shí),那么它傳遞的是引用這么一個(gè)思想來進(jìn)行實(shí)現(xiàn),貼出代碼供大家參考

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將有父子關(guān)系的數(shù)據(jù)轉(zhuǎn)換成樹形結(jié)構(gòu)數(shù)據(jù)

數(shù)據(jù)庫父子結(jié)構(gòu)數(shù)據(jù)設(shè)計(jì)

大部分采用 parentId的形式來存儲(chǔ)父id,并且只存儲(chǔ)父id,祖父Id不存儲(chǔ)。也可以添加存儲(chǔ)層級(jí)級(jí)別或者層級(jí)關(guān)系等字段。

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 '層級(jí)級(jí)別',
  `decode` varchar(255) DEFAULT NULL COMMENT '層級(jí)ID的關(guān)系,用”_“分割',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

將有父子關(guān)系的數(shù)據(jù)轉(zhuǎn)換成樹形結(jié)構(gòu)數(shù)據(jù)

mapper層獲取數(shù)據(jù)庫數(shù)據(jù)和 controller層處理很簡單,將有父子關(guān)系的數(shù)據(jù)轉(zhuǎn)換成樹形結(jié)構(gòu)數(shù)據(jù)交給 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、方式一:遞歸:從樹的最頂級(jí)獲取子級(jí),然后子級(jí)獲取其子級(jí)。

返回時(shí),需要哪些字段值就添加哪些字段值到 map中。結(jié)果圖如上

    /**
     * 將有父子關(guān)系的數(shù)據(jù)轉(zhuǎn)換成樹形結(jié)構(gòu)數(shù)據(jù)
     *
     * @return 最終的樹狀結(jié)構(gòu)的集合數(shù)據(jù)
     */
    @Override
    public List<Map<String, Object>> getMuneTree() {
        // 獲取數(shù)據(jù)庫中帶有有父子關(guān)系的數(shù)據(jù)
        List<ResourceDO> data = resourceDOMapper.selectAll();
        //創(chuàng)建一個(gè)List集合來存放最終的樹狀結(jié)構(gòu)數(shù)據(jù)
        List<Map<String, Object>> menuList = new ArrayList<>();
        // 先存入最頂級(jí)的樹(0代表沒有父級(jí),即最頂級(jí)),然后通過最頂級(jí)的id遞歸獲取子級(jí)
        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獲取子級(jí),查詢子級(jí)下的子級(jí)
     *
     * @param data 數(shù)據(jù)庫的原始數(shù)據(jù)
     * @param id   主id
     * @return  該id下得子級(jí)
     */
    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<>();
            //如果本級(jí)id與數(shù)據(jù)的父id相同,就說明是子父級(jí)關(guān)系
            if (id.equals(entity.getParentId())) {
                map.put("id", entity.getId());
                map.put("parentId", entity.getParentId());
                map.put("name", entity.getName());
                //查詢子級(jí)下的子級(jí)
                map.put("children", getChildren(data, entity.getId()));
                list.add(map);
            }
        }
        return list;
    }

2、方式二:組裝帶有children關(guān)聯(lián)性的對(duì)象

在實(shí)體列中定義一個(gè) children集合:

    private List<ResourceDO> children = new ArrayList<>();

返回的是實(shí)體類對(duì)象的所有值,這里操作的都是集合存儲(chǔ)對(duì)象的引用

    /**
     * 將有父子關(guān)系的數(shù)據(jù)轉(zhuǎn)換成樹形結(jié)構(gòu)數(shù)據(jù)
     *
     * @return 最終的樹狀結(jié)構(gòu)的集合數(shù)據(jù)
     */
    @Override
    public List<ResourceDO> getMuneTree2() {
        // 獲取數(shù)據(jù)庫中帶有有父子關(guān)系的數(shù)據(jù)
        List<ResourceDO> data = resourceDOMapper.selectAll();
        // 復(fù)制data數(shù)據(jù)
        List<ResourceDO> menuList = new ArrayList<>(data);
        // 遍歷兩次data來組裝帶有children關(guān)聯(lián)性的對(duì)象,如果找到子級(jí)就刪除menuList的數(shù)據(jù)
        for (ResourceDO entity : data) {
            for (ResourceDO entity2 : data) {
                //如果本級(jí)id與數(shù)據(jù)的父id相同,就說明是子父級(jí)關(guān)系
                if (entity.getId().equals(entity2.getParentId())) {
                    entity.getChildren().add(entity2);
                    menuList.remove(entity2);
                }
            }
        }
        return menuList;
    }

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java的Spring框架中bean的定義以及生命周期

    詳解Java的Spring框架中bean的定義以及生命周期

    這篇文章主要介紹了Java的Spring框架中bean的定義以及生命周期,bean的實(shí)例化是Java web開發(fā)中的重要基礎(chǔ),需要的朋友可以參考下
    2015-12-12
  • springboot連接不同數(shù)據(jù)庫的寫法詳解

    springboot連接不同數(shù)據(jù)庫的寫法詳解

    這篇文章主要介紹了springboot連接不同數(shù)據(jù)庫的寫法?,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • springBoot中myBatisPlus的使用步驟及示例代碼

    springBoot中myBatisPlus的使用步驟及示例代碼

    MyBatis-Plus 是一個(gè) MyBatis 的增強(qiáng)工具,在 Spring Boot 項(xiàng)目里使用它能極大提升開發(fā)效率,下面為你詳細(xì)介紹在 Spring Boot 中使用 MyBatis-Plus 的步驟以及示例代碼,感興趣的朋友一起看看吧
    2025-03-03
  • springboot項(xiàng)目啟動(dòng)優(yōu)化的超強(qiáng)方法詳解

    springboot項(xiàng)目啟動(dòng)優(yōu)化的超強(qiáng)方法詳解

    本篇文章主要為大家詳細(xì)介紹了SpringBoot中項(xiàng)目啟動(dòng)速度優(yōu)化的方法相關(guān)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過來看看吧
    2025-10-10
  • Java OOM 異常場(chǎng)景與排查過程(堆、棧、方法區(qū))

    Java OOM 異常場(chǎng)景與排查過程(堆、棧、方法區(qū))

    這篇文章主要介紹了Java OOM 異常場(chǎng)景與排查過程(堆、棧、方法區(qū)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • MyBatis插件機(jī)制的使用及說明

    MyBatis插件機(jī)制的使用及說明

    MyBatis插件機(jī)制通過攔截器實(shí)現(xiàn),允許開發(fā)者在不修改源代碼的情況下擴(kuò)展和定制MyBatis功能,主要攔截方法包括Executor、ParameterHandler、ResultSetHandler和StatementHandler,攔截器通過XML配置或Java代碼定義,實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的方法調(diào)用攔截和增強(qiáng)
    2026-01-01
  • SpringCloud Gateway路由核心原理解析

    SpringCloud Gateway路由核心原理解析

    本文主要介紹了SpringCloudGateway的基礎(chǔ)構(gòu)建塊、工作原理以及核心原理解析,SpringCloudGateway是Spring官方基于SpringSpringBoot和ProjectReactor等技術(shù)開發(fā)的網(wǎng)關(guān),旨在為微服務(wù)架構(gòu)提供一種簡單而有效的統(tǒng)一的API路由管理方式
    2024-10-10
  • 詳解SpringMVC使用MultipartFile實(shí)現(xiàn)文件的上傳

    詳解SpringMVC使用MultipartFile實(shí)現(xiàn)文件的上傳

    本篇文章主要介紹了SpringMVC使用MultipartFile實(shí)現(xiàn)文件的上傳,本地的文件上傳到資源服務(wù)器上,比較好的辦法就是通過ftp上傳。這里是結(jié)合SpringMVC+ftp的形式上傳的,有興趣的可以了解一下。
    2016-12-12
  • Java?awt-對(duì)話框簡單實(shí)現(xiàn)方式

    Java?awt-對(duì)話框簡單實(shí)現(xiàn)方式

    這篇文章主要介紹了Java?awt-對(duì)話框簡單實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringCloud Ribbon負(fù)載均衡實(shí)例解析

    SpringCloud Ribbon負(fù)載均衡實(shí)例解析

    這篇文章主要介紹了SpringCloud Ribbon負(fù)載均衡實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評(píng)論

茶陵县| 湛江市| 涿州市| 太谷县| 睢宁县| 华宁县| 扶沟县| 连南| 文山县| 常宁市| 固安县| 新乡县| 长春市| 叙永县| 霸州市| 河曲县| 海林市| 镇平县| 澄江县| 五华县| 澳门| 仁布县| 天长市| 铅山县| 山东省| 阜阳市| 屏边| 英超| 绍兴市| 禄丰县| 额敏县| 台前县| 新闻| 五台县| 凤冈县| 北安市| 淳化县| 土默特右旗| 达拉特旗| 万盛区| 登封市|