中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java怎么用遞歸實現樹形結構的工具類

發布時間:2023-03-09 15:30:49 來源:億速云 閱讀:98 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Java怎么用遞歸實現樹形結構的工具類”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java怎么用遞歸實現樹形結構的工具類”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

需求描述

有時候,我們的數據是帶有層級的,比如常見的省市區三級聯動,就是一層套著一層,如下圖:

Java怎么用遞歸實現樹形結構的工具類

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

Java怎么用遞歸實現樹形結構的工具類

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

使用示例

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

  • @TreeKey 標識唯一

  • @TreeParentKey 標識父節點標識

  • @TreeChildren 標識子孫節點集合

@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", "武侯區", "510100"));
        places.add(new Place("510116", "雙流區", "510100"));
        places.add(new Place("511600", "廣安市", "510000"));
        places.add(new Place("511603", "前鋒區", "511600"));
        places.add(new Place("511621", "岳池縣", "511600"));
        List<Place> treeList = TreeUtils.getTree(places, "0");
        System.out.println(JSON.toJSONString(treeList));
    }

}

最終效果:

Java怎么用遞歸實現樹形結構的工具類

工具代碼

@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 {

    /**
     * 集合轉化為樹形
     *
     * @param list             集合
     * @param highestParentKey 最高層父節點值
     * @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);
        // 獲取最高層數據
        List<T> highs = new ArrayList<>();
        try {
            for (T t : list) {
                Object pk = parentKey.get(t);
                if (getString(pk).equals(getString(highestParentKey))) {
                    highs.add(t);
                }
            }
            // 獲取最高層子孫節點
            for (T t : highs) {
                setChildren(list, t, key, parentKey, children);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return highs;
    }

    /**
     * 獲取子孫節點
     *
     * @param list      集合
     * @param parent    父節點對象
     * @param key       唯一屬性
     * @param parentKey 父唯一屬性
     * @param children  節點
     * @param <T>       泛型
     * @return 帶有子孫集合的父節點對象
     * @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怎么用遞歸實現樹形結構的工具類”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石城县| 龙岩市| 开江县| 清流县| 斗六市| 石景山区| 六盘水市| 蒙城县| 博乐市| 常宁市| 满洲里市| 互助| 涿鹿县| 漳平市| 古蔺县| 环江| 黑河市| 武穴市| 曲松县| 仁布县| 长顺县| 合江县| 海口市| 高安市| 胶南市| 乌拉特前旗| 新晃| 叙永县| 延津县| 多伦县| 城市| 富民县| 丹阳市| 泸西县| 吉安市| 赞皇县| 宁阳县| 宕昌县| 砀山县| 黔西县| 阿瓦提县|