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

Java利用遞歸實現(xiàn)樹形結(jié)構(gòu)的工具類

 更新時間:2023年03月09日 14:48:30   作者:zyqok  
有時候,我們的數(shù)據(jù)是帶有層級的,比如常見的省市區(qū)三級聯(lián)動,就是一層套著一層。而我們在數(shù)據(jù)庫存放數(shù)據(jù)的時候,往往是列表形式的,這個時候可能就需要遞歸處理為樹形結(jié)構(gòu)了。本文就為大家介紹了Java利用遞歸實現(xiàn)樹形結(jié)構(gòu)的工具類,希望對大家有所幫助

需求描述

有時候,我們的數(shù)據(jù)是帶有層級的,比如常見的省市區(qū)三級聯(lián)動,就是一層套著一層,如下圖:

而我們在數(shù)據(jù)庫存放數(shù)據(jù)的時候,往往是列表形式的,如下圖:

那么當我們從數(shù)據(jù)庫查詢出來,返回給前端的時候,前端又需要給出樹形層級的時候,這個時候可能就需要遞歸處理為樹形結(jié)構(gòu)了,因此下面這個工具或許就可以用得上了。

使用示例

我們按照上面定義一個Place對象,打上工具注解:

  • @TreeKey 標識唯一
  • @TreeParentKey 標識父節(jié)點標識
  • @TreeChildren 標識子孫節(jié)點集合
@Data
@Data
public class Place {

    @TreeKey
    private String id;

    @TreeParentKey
    private String parentId;

    private String name;

    @TreeChildren
    private List<Place> children;

    public Place(String id, String name, String parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }
}

測試:

public class Test {

    public static void main(String[] args) {
        List<Place> places = new ArrayList<>();
        places.add(new Place("510000", "四川省", "0"));
        places.add(new Place("510100", "成都市", "510000"));
        places.add(new Place("510107", "武侯區(qū)", "510100"));
        places.add(new Place("510116", "雙流區(qū)", "510100"));
        places.add(new Place("511600", "廣安市", "510000"));
        places.add(new Place("511603", "前鋒區(qū)", "511600"));
        places.add(new Place("511621", "岳池縣", "511600"));
        List<Place> treeList = TreeUtils.getTree(places, "0");
        System.out.println(JSON.toJSONString(treeList));
    }

}

最終效果:

工具代碼

@TreeKey

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeKey {
}

@TreeParentKey

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeParentKey {
}

@TreeChildren

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeChildren {
}

@TreeUtils

package com.csd.utils.tree;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 遞歸求樹形工具類
 *
 * @author Yuanqiang.Zhang
 * @since 2023/3/8
 */
public class TreeUtils {

    /**
     * 集合轉(zhuǎn)化為樹形
     *
     * @param list             集合
     * @param highestParentKey 最高層父節(jié)點值
     * @param <T>              泛型
     * @return 樹形
     */
    public static <T> List<T> getTree(List<T> list, Object highestParentKey) {
        if (Objects.isNull(list) || list.isEmpty()) {
            return Collections.emptyList();
        }
        Field key = null;
        Field parentKey = null;
        Field children = null;
        Field[] fields = list.get(0).getClass().getDeclaredFields();
        for (Field field : fields) {
            if (Objects.isNull(key)) {
                TreeKey treeKey = field.getAnnotation(TreeKey.class);
                if (Objects.nonNull(treeKey)) {
                    key = field;
                    continue;
                }
            }
            if (Objects.isNull(parentKey)) {
                TreeParentKey treeParentKey = field.getAnnotation(TreeParentKey.class);
                if (Objects.nonNull(treeParentKey)) {
                    parentKey = field;
                    continue;
                }
            }
            if (Objects.isNull(children)) {
                TreeChildren treeChildren = field.getAnnotation(TreeChildren.class);
                if (Objects.nonNull(treeChildren)) {
                    children = field;
                    continue;
                }
            }
        }
        if (Objects.isNull(key) || Objects.isNull(parentKey) || Objects.isNull(children)) {
            return Collections.emptyList();
        }
        key.setAccessible(true);
        parentKey.setAccessible(true);
        children.setAccessible(true);
        // 獲取最高層數(shù)據(jù)
        List<T> highs = new ArrayList<>();
        try {
            for (T t : list) {
                Object pk = parentKey.get(t);
                if (getString(pk).equals(getString(highestParentKey))) {
                    highs.add(t);
                }
            }
            // 獲取最高層子孫節(jié)點
            for (T t : highs) {
                setChildren(list, t, key, parentKey, children);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return highs;
    }

    /**
     * 獲取子孫節(jié)點
     *
     * @param list      集合
     * @param parent    父節(jié)點對象
     * @param key       唯一屬性
     * @param parentKey 父唯一屬性
     * @param children  節(jié)點
     * @param <T>       泛型
     * @return 帶有子孫集合的父節(jié)點對象
     * @throws IllegalAccessException
     */
    private static <T> T setChildren(List<T> list, T parent, Field key, Field parentKey, Field children) throws IllegalAccessException {
        Object k = key.get(parent);
        List<T> tempList = new ArrayList<>();
        for (T t : list) {
            Object pk = parentKey.get(t);
            if (getString(k).equals(getString(pk))) {
                tempList.add(setChildren(list, t, key, parentKey, children));
            }
        }
        children.set(parent, tempList);
        return parent;
    }

    /**
     * 獲取字符串
     *
     * @param o 值
     * @return 字符串
     */
    private static String getString(Object o) {
        return Objects.isNull(o) ? "" : o.toString();
    }

}

以上就是Java利用遞歸實現(xiàn)樹形結(jié)構(gòu)的工具類的詳細內(nèi)容,更多關(guān)于Java樹形結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java并發(fā)編程專題(四)----淺談(JUC)Lock鎖

    java并發(fā)編程專題(四)----淺談(JUC)Lock鎖

    這篇文章主要介紹了java并發(fā)編程(JUC)Lock鎖的相關(guān)內(nèi)容,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-06-06
  • Java集合教程之Collection實例詳解

    Java集合教程之Collection實例詳解

    集合,或者叫容器,是一個包含多個元素的對象,下面這篇文章主要給大家介紹了關(guān)于Java集合教程之Collection的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-08-08
  • SpringBoot中并發(fā)定時任務(wù)的實現(xiàn)、動態(tài)定時任務(wù)的實現(xiàn)(看這一篇就夠了)推薦

    SpringBoot中并發(fā)定時任務(wù)的實現(xiàn)、動態(tài)定時任務(wù)的實現(xiàn)(看這一篇就夠了)推薦

    這篇文章主要介紹了SpringBoot并發(fā)定時任務(wù)動態(tài)定時任務(wù)實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Java多線程的調(diào)度_動力節(jié)點Java學院整理

    Java多線程的調(diào)度_動力節(jié)點Java學院整理

    有多個線程,如何控制它們執(zhí)行的先后次序呢?下文給大家分享四種方法及java多線程調(diào)度的實例代碼,需要的朋友參考下吧
    2017-05-05
  • Java開發(fā)崗位面試被問到嵌套類怎么辦

    Java開發(fā)崗位面試被問到嵌套類怎么辦

    本篇文章主要介紹了深入理解Java嵌套類和內(nèi)部類,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-07-07
  • Spring中@Autowired自動注入map詳解

    Spring中@Autowired自動注入map詳解

    這篇文章主要介紹了Spring中@Autowired自動注入map詳解,  spring是支持基于接口實現(xiàn)類的直接注入的,支持注入map,list等集合中,不用做其他的配置,直接注入,需要的朋友可以參考下
    2023-10-10
  • spring中AOP 注解開發(fā)示例詳解

    spring中AOP 注解開發(fā)示例詳解

    這篇文章主要介紹了spring中AOP注解開發(fā)的相關(guān)資料,文中介紹的很詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 簡單了解Java創(chuàng)建線程兩種方法

    簡單了解Java創(chuàng)建線程兩種方法

    這篇文章主要介紹了簡單了解Java創(chuàng)建線程兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Java基礎(chǔ)之異常處理詳解

    Java基礎(chǔ)之異常處理詳解

    異常可能是在程序執(zhí)行過程中產(chǎn)生的,也可能是程序中throw主動拋出的。本文主要給大家介紹了Java中異常處理的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • java簡單手寫版本實現(xiàn)時間輪算法

    java簡單手寫版本實現(xiàn)時間輪算法

    這篇文章主要為大家詳細介紹了java簡單手寫版本實現(xiàn)時間輪算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評論

茌平县| 临清市| 恩平市| 六枝特区| 广饶县| 名山县| 富顺县| 湘潭市| 河池市| 会理县| 海南省| 大丰市| 崇阳县| 齐齐哈尔市| 浦东新区| 普陀区| 交城县| 南投县| 城口县| 葫芦岛市| 石景山区| 荣昌县| 潼关县| 德阳市| 南开区| 宁化县| 哈密市| 缙云县| 凯里市| 故城县| 吉安县| 隆昌县| 香港 | 师宗县| 含山县| 陇南市| 上思县| 方城县| 屯昌县| 玉溪市| 仲巴县|