java構建樹形列表(帶children屬性)


一些前端框架提供的樹形表格需要手動構建樹形列表(帶children屬性的對象數組),這種結構一般是需要在Java后台構建好。

構建的方式是通過id字段與父id字段做關聯,通過遞歸構建children字段來達到構建樹形列表的目的。

/**
 * 樹形表格工具類
 *
 * @author yanggb
 */
public class TreeTableUtil {/**
     * 把列表轉換為樹結構
     *
     * @param originalList      原始list數據
     * @param idFieldName       作為唯一標示的字段名稱
     * @param pidFieldName      父節點標識字段名
     * @param childrenFieldName 子節點(列表)標識字段名
     * @return 樹結構列表
     */
    public static <T> List<T> list2TreeList(List<T> originalList, String idFieldName, String pidFieldName,
                                            String childrenFieldName) {
        // 獲取根節點,即找出父節點為空的對象
        List<T> rootNodeList = new ArrayList<>();
        for (T t : originalList) {
            String parentId = null;
            try {
                parentId = BeanUtils.getProperty(t, pidFieldName);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
            if (StringUtils.isBlank(parentId)) {
                rootNodeList.add(0, t);
            }
        }

        // 將根節點從原始list移除,減少下次處理數據
        originalList.removeAll(rootNodeList);

        // 遞歸封裝樹
        try {
            packTree(rootNodeList, originalList, idFieldName, pidFieldName, childrenFieldName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rootNodeList;
    }

    /**
     * 封裝樹(向下遞歸)
     *
     * @param parentNodeList    要封裝為樹的父節點對象集合
     * @param originalList      原始list數據
     * @param keyName           作為唯一標示的字段名稱
     * @param pidFieldName      父節點標識字段名
     * @param childrenFieldName 子節點(列表)標識字段名
     */
    private static <T> void packTree(List<T> parentNodeList, List<T> originalList, String keyName,
                                     String pidFieldName, String childrenFieldName) throws Exception {
        for (T parentNode : parentNodeList) {
            // 找到當前父節點的子節點列表
            List<T> children = packChildren(parentNode, originalList, keyName, pidFieldName, childrenFieldName);
            if (children.isEmpty()) {
                continue;
            }

            // 將當前父節點的子節點從原始list移除,減少下次處理數據
            originalList.removeAll(children);

            // 開始下次遞歸
            packTree(children, originalList, keyName, pidFieldName, childrenFieldName);
        }
    }

    /**
     * 封裝子對象
     *
     * @param parentNode        父節點對象
     * @param originalList      原始list數據
     * @param keyName           作為唯一標示的字段名稱
     * @param pidFieldName      父節點標識字段名
     * @param childrenFieldName 子節點(列表)標識字段名
     */
    private static <T> List<T> packChildren(T parentNode, List<T> originalList, String keyName, String pidFieldName,
                                            String childrenFieldName) throws Exception {
        // 找到當前父節點下的子節點列表
        List<T> childNodeList = new ArrayList<>();
        String parentId = BeanUtils.getProperty(parentNode, keyName);
        for (T t : originalList) {
            String childNodeParentId = BeanUtils.getProperty(t, pidFieldName);
            if (parentId.equals(childNodeParentId)) {
                childNodeList.add(t);
            }
        }

        // 將當前父節點下的子節點列表寫入到當前父節點下(給子節點列表字段賦值)
        if (!childNodeList.isEmpty()) {
            FieldUtils.writeDeclaredField(parentNode, childrenFieldName, childNodeList, true);
        }

        return childNodeList;
    }
}

直接上代碼就好了,我相信禿頭的你一定能看得懂。

 

"這個世界並不在乎你的自尊,只在乎你做出來的成績,然后再去強調你的感受。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM