將List構建成前臺下拉樹展示樣式

TreeNode.java

import lombok.Data;

import java.util.List;

@Data
public class TreeNode<T> {
    /**
     * 節點編號
     */
    private String id;
    /**
     * 父節點編號
     */
    private String pid;
    /**
     * 節點名稱
     */
    private String title;
    /**
     * 數據
     */
    private T data;
    /**
     * 子節點
     */
    private List<TreeNode<T>> children;
}

TreeUtil.java

import TreeNode;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author
 * @date
 */
public class TreeUtil {
    /**
     * 將List構建成前臺展示樹的格式(根節點,層層包含所有子節點)
     * @param list 樹形結構列表
     * @param idName 節點編號
     * @param pidName 父節點編號
     * @param titleName 節點名稱
     * @param <T>
     * @return
     */
    public static <T> List<TreeNode<T>> buildTree(List<T> list, String idName, String pidName, String titleName) {
        // 將list構建成樹節點的樣式
        List<TreeNode<T>> treeNodes = buildTreeNodes(list, idName, pidName, titleName);
        // 獲取根節點列表
        List<TreeNode<T>> rootNodes = getTreeRootNodes(treeNodes);
        // 迭代遞歸出根節點下所有子節點
        Map<String, List<TreeNode<T>>> pidGroup = treeNodes.stream().collect(Collectors.groupingBy(TreeNode::getPid));
        Iterator<TreeNode<T>> it = rootNodes.iterator();
        while (it.hasNext()) {
            setChildNodes(pidGroup, it.next());
        }
        return rootNodes;
    }

    /**
     * 獲取根節點列表
     * @param list
     * @return
     */
    private static <T> List<TreeNode<T>> getTreeRootNodes(List<TreeNode<T>> list) {
        // 獲取所有節點id
        Set<String> idSet = list.stream().map(TreeNode::getId).collect(Collectors.toSet());
        // 篩選出所有根節點(如果父節點不在節點id列表上則表示該節點爲父節點)
        List<TreeNode<T>> rootNodes = list.stream().filter(treeNode -> !idSet.contains(treeNode.getPid())).collect(Collectors.toList());
        return rootNodes;
    }

    /**
     * 設置所有子節點
     * @param pidGroupt
     * @param parentNode
     * @param <T>
     */
    private static <T> void setChildNodes(Map<String, List<TreeNode<T>>> pidGroupt, TreeNode<T> parentNode) {
        // 獲取父節點直接下掛的所有子節點
        List<TreeNode<T>> children = pidGroupt.get(parentNode.getId());
        if (CollectionUtils.isNotEmpty(children)) {
            // 迭代每個子節點,爲每個子節點設置它們直接下掛的所有子節點
            Iterator<TreeNode<T>> iterator = children.iterator();
            while (iterator.hasNext()) {
                setChildNodes(pidGroupt,iterator.next());
            }
            parentNode.setChildren(children);
        }
    }

    /**
     * 將List構建成樹節點的樣式(多個節點)
     * @param list
     * @param idName
     * @param pidName
     * @param titleName
     * @param <T>
     * @return
     */
    private static <T> List<TreeNode<T>> buildTreeNodes(List<T> list, String idName, String pidName, String titleName) {
        List<TreeNode<T>> treeNodes = new ArrayList<>();
        // 將list構建成樹節點的樣式
        for (T item:list) {
            treeNodes.add(buildTreeNode(item, idName, pidName, titleName));
        }
        return treeNodes;
    }

    /**
     * 將對象構建成樹節點的樣式(單個節點)
     * @param obj
     * @param idName
     * @param pidName
     * @param titleName
     * @return
     */
    private static TreeNode buildTreeNode(Object obj, String idName, String pidName, String titleName){
        // 獲取對象屬性值
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
        TreeNode treeNode = new TreeNode();
        treeNode.setId((String) beanWrapper.getPropertyValue(idName));
        treeNode.setPid((String) beanWrapper.getPropertyValue(pidName));
        treeNode.setTitle((String) beanWrapper.getPropertyValue(titleName));
        treeNode.setData(obj);
        return treeNode;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章