Skip to content
鼓励作者:欢迎打赏犒劳

List工具类

list和树互转

TreeNodeUtil

泛型基类

java
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 树节点结构 的基类。 要想用  TreeNodeUtil 工具类  必须继承这个类才可以进行转换
 */
@Data
public class TreeNode<K,T> implements Serializable {

    /** 主键 */
    private K id;

    /** 父菜单ID */
    private K parentId;

    /** 导航名字 */
    private String name;

    /** 排序 */
    private Integer sort;
    
     /** 层级 */
    private Integer deep;

    /** 下级节点 */
    List<T> childList = new ArrayList<>();
}

工具类

java
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
 * 树工具类  
 * 公众号:干货食堂
 */
public class TreeNodeUtil {

    /**
     * list 转 tree
     * @param list
     * @param parentId
     * @param deep  树深度
     * @return
     */
    public static <K, T extends TreeNode<K, T>> List<T>  convertTreeNode(List<T> list, K parentId, Integer deep){
        //子类
        List<T> children = list.stream().filter(x -> x.getParentId().equals(parentId)).collect(Collectors.toList());
        children.forEach(e -> e.setDeep(deep));
        //排序,即便是sql不排序 也可以用代码实现
        children = children.stream().sorted(Comparator.comparing(T::getSort)).collect(Collectors.toList());
        //后辈中的非子类
        List<T> successor = list.stream().filter(x -> !x.getParentId().equals(parentId)).collect(Collectors.toList());

        children.forEach(x ->
                {
                    convertTreeNode(successor, (K)x.getId(),deep + 1).forEach(
                            y  -> x.getChildList().add(y)
                    );
                }
        );
        return children;
    }


    public static <T extends TreeNode> List<T> convertTreeNode(List<T> dataList) {
        //key 级别,值 数据列表
        Map<Integer, List<T>> levelMap = dataList.stream().
                collect(Collectors.groupingBy(e -> e.getDeep(), TreeMap::new, Collectors.toList()));
        //所有级别
        List<Integer> levelList = levelMap.keySet().stream().sorted().collect(Collectors.toList());

        for (Integer level : levelList) {
            //获取当前级别的数据列表
            List<T> tableDataList = levelMap.get(level);
            int childLevel = level + 1;

            List<T> childTableDataList = levelMap.get(childLevel);

            if (childTableDataList == null || childTableDataList.size() == 0) break;

            for (T tableData : tableDataList) {
                List<T> childList = childTableDataList.parallelStream()
                        .filter(child -> child.getParentId().equals(tableData.getId()))
                        .sorted(Comparator.comparing(e -> e.getSort()))
                        .collect(Collectors.toList());

                tableData.setChildList(childList);
            }
        }
        return levelMap.get(1).stream().sorted(Comparator.comparing(e -> e.getSort())).collect(Collectors.toList());
    }


    /**
     * tree 转 list
     * @param list
     * @param target
     */
    public static <T extends TreeNode> void treeToList(List<T> list, List<T> target){
        for (int i = 0; i < list.size(); i++) {
            T my_menuNode = list.get(i);
            List<T> children = my_menuNode.getChildList();
            children = children.stream().sorted(Comparator.comparing(T::getSort)).collect(Collectors.toList());
            if (children.size()>0){
                treeToList(children,target);
            }
            target.add(my_menuNode);
        }
    }
}

TreeNodeUtil2

java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 树工具类  
 * 公众号:干货食堂
 */
public class TreeNodeUtil2{

    /**
     * 递归向上查找法
     */
    public static  <K, T extends TreeNode<K, T>> List<T> convertTreeNode(List<T> nodeList) {
        Map<K, T> nodeMap = new LinkedHashMap<>(16);
        for (T node : nodeList) {
            nodeMap.put(node.getId(), node);
        }
        return buildTree(nodeMap);
    }

    /**
     * 递归向上查找父节点
     */
    public static  <K, T extends TreeNode<K, T>> List<T> buildTree(Map<K, T> nodeMap) {
        return findParent(nodeMap);
    }

    /**
     * 利用HashMap高效率递归向上查找,并每次减少遍历节点数
     */
    public static <K, T extends TreeNode<K, T>> List<T> findParent(Map<K, T> nodeMap) {

        //该循环结束后可以移除掉的节点
        List<K> removeNodes = new ArrayList<>();

        for (T node : nodeMap.values()) {
            T pNode = nodeMap.get(node.getParentId());
            //如果当前节点的父节点存在,则将当前节点添加到父节点的子节点,并在循环结束后从Map中删除当前节点
            if (pNode != null) {
                pNode.getChildList().add(node);
                removeNodes.add(node.getId());
            }
        }
        //删除已经找到父节点的节点
        removeNodes.forEach(nodeMap::remove);

        List<T> treeList = new ArrayList<>(nodeMap.values());
        return sortTree(treeList);
    }



    /**
     * 遍历并排序树结构
     * @param treeList 树结构列表
     * @return 排序后的树结构列表
     */
    public static <K, T extends TreeNode<K, T>> List<T> sortTree(List<T> treeList) {
        // 对树的根节点进行排序
        treeList = treeList.stream()
                .sorted(Comparator.comparing(T::getSort))
                .collect(Collectors.toList());

        Integer deep = 1;
        // 遍历每个节点,并递归排序其子节点
        treeList.forEach(e -> {
            e.setDeep(deep);
            sortChildren(e,deep);
        });
        return treeList;
    }

    /**
     * 递归排序节点的子节点
     * @param node 当前节点
     */
    private static <K, T extends TreeNode<K, T>> void sortChildren(T node,Integer deep) {
        List<T> children = node.getChildList();
        if (children != null && !children.isEmpty()) {
            // 对子节点进行排序
            children = children.stream()
                    .sorted(Comparator.comparing(T::getSort))
                    .collect(Collectors.toList());

            // 更新当前节点的子节点列表
            node.setChildList(children);

            // 递归排序每个子节点的子节点
            deep+=1;
            Integer finalDeep = deep;
            children.forEach(e -> {
                e.setDeep(finalDeep);
                sortChildren(e, finalDeep);
            });
        }
    }
}

Map结构

map比较特殊,专门写一个

java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 树工具类  
 */
public class TreeNodeUtil3 {

    /**
     * 递归向上查找法
     */
    public static  List<Map<String,Object>> convertTreeNode(List<Map<String,Object>> nodeList) {
        Map<String,Map<String,Object>> nodeMap = new LinkedHashMap<>(16);
        for (Map<String,Object> node : nodeList) {
            nodeMap.put(node.get("id").toString(), node);
        }
        return buildTree(nodeMap);
    }

    /**
     * 递归向上查找父节点
     */
    private static   List<Map<String,Object>> buildTree(Map<String,Map<String,Object>> nodeMap) {
        return findParent(nodeMap);
    }

    /**
     * 利用HashMap高效率递归向上查找,并每次减少遍历节点数
     */
    private static  List<Map<String,Object>> findParent(Map<String,Map<String,Object>> nodeMap) {

        //该循环结束后可以移除掉的节点
        List<String> removeNodes = new ArrayList<>();

        for (Map<String,Object> node : nodeMap.values()) {
            Map<String,Object> pNode = nodeMap.get(node.get("pId").toString());
            //如果当前节点的父节点存在,则将当前节点添加到父节点的子节点,并在循环结束后从Map中删除当前节点
            if (pNode != null) {
                ((ArrayList)pNode.get("child")).add(node);
                removeNodes.add(node.get("id").toString());
            }
        }
        //删除已经找到父节点的节点
        removeNodes.forEach(nodeMap::remove);

        List<Map<String,Object>> treeList = new ArrayList<>(nodeMap.values());
        return sortTree(treeList);
    }



    /**
     * 遍历并排序树结构
     * @param treeList 树结构列表
     * @return 排序后的树结构列表
     */
    private static  List<Map<String,Object>> sortTree(List<Map<String,Object>> treeList) {
        // 对树的根节点进行排序
        treeList = treeList.stream()
                .sorted(Comparator.comparing(m -> (Integer)m.get("sort")))
                .collect(Collectors.toList());

        Integer deep = 1;
        // 遍历每个节点,并递归排序其子节点
        treeList.forEach(e -> {
            e.put("deep",deep);
            sortChildren(e,deep);
        });
        return treeList;
    }

    /**
     * 递归排序节点的子节点
     * @param node 当前节点
     */
    private static  void sortChildren(Map<String,Object> node,Integer deep) {
        List<Map<String,Object>> children = (List<Map<String,Object>>)node.get("child");
        if (children != null && !children.isEmpty()) {
            // 对子节点进行排序
            children = children.stream()
                    .sorted(Comparator.comparing(m -> (Integer)m.get("sort")))
                    .collect(Collectors.toList());

            // 更新当前节点的子节点列表
            node.put("child",children);

            // 递归排序每个子节点的子节点
            deep+=1;
            Integer finalDeep = deep;
            children.forEach(e -> {
                e.put("deep",finalDeep);
                sortChildren(e, finalDeep);
            });
        }
    }
}

验证

java
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class Test2 {
    @Test
    public  void test() {
        long a = System.currentTimeMillis();
        List<List<String>> listData = new ArrayList<>();
        listData.add(Arrays.asList("PH", "MY","SG","ID","TH","SEA"));
        listData.add(Arrays.asList("Total","CN_VMI", "CN_JIT", "Local_VMI", "Local_JIT"));
        listData.add(Arrays.asList("Tag1", "Tag2","Tag3"));
        listData.add(getDateList("2024-01-01","2024-12-02"));

        List<List<String>> list2 = getDescartes(listData);
//        System.out.println(list2);
        Random random = new Random();
        List<Map<String,Object>> treeNodes = new ArrayList<>();
        for (int i = 0; i < list2.size(); i++) {
            List<String> list = list2.get(i);
            for (int j = 0; j < list.size(); j++) {
                String ele = list.get(j);

                Map<String, Object> treeNode = new HashMap<>();
                treeNode.put("id",StringUtils.join(list.subList(0, j+1),"#"));
                treeNode.put("pId",j == 0 ? "#" : StringUtils.join(list.subList(0, j),"#"));
                treeNode.put("name",ele);
                treeNode.put("level",j+1);
                treeNode.put("sort",random.nextInt(5));
                treeNode.put("child",new ArrayList<>());
                treeNodes.add(treeNode);
            }
        }
        // 去重
        long b = System.currentTimeMillis();
        System.out.println("基础数据条数:"+treeNodes.size());
        System.out.println("准备数据耗时:" + (b - a));

        List<Map<String,Object>> treeNodes2 = TreeNodeUtil3.convertTreeNode(treeNodes);
        long d = System.currentTimeMillis();
        System.out.println("第二种方法性能耗时:" + (d - b));
    }



    private static <T> List<List<T>> getDescartes(List<List<T>> list) {
        List<List<T>> returnList = new ArrayList<>();
        descartesRecursive(list, 0, returnList, new ArrayList<>());
        return returnList;
    }

    private static <T> void descartesRecursive(List<List<T>> originalList, int position, List<List<T>> returnList, List<T> cacheList) {
        List<T> currentList = originalList.get(position); // 获取当前需要处理的子列表
        for (int i = 0; i < currentList.size(); i++) {
            List<T> childCacheList = new ArrayList<>(cacheList);
            childCacheList.add(currentList.get(i));

            // 判断是否已经处理到原始列表的最后一个子列表,如果是,则将当前组合添加到结果列表中
            if (childCacheList.size() == originalList.size()) {
                returnList.add(childCacheList);
            } else {
                // 否则继续对下一个子列表进行同样的操作
                descartesRecursive(originalList, position + 1, returnList, childCacheList);
            }
        }
    }
    /**
     * 获取两个日期之间的所有日期集合
     *
     * @param startDate
     * @param endDate
     * @return
     */
    private static List<String> getDateList(String startDate, String endDate){
        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> listDate = new ArrayList<>();
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateFormat.parse(startDate));
            while (calendar.getTime().before(dateFormat.parse(endDate)) || calendar.getTime().equals(dateFormat.parse(endDate))) {
                listDate.add(dateFormat.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
            return listDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return listDate;
    }
}

如有转载或 CV 的请标注本站原文地址