【工具类】任意类型的数据对象集合转换为树结构,高效率,支持排序,编程式函数调用

找了一下ai提供的和本博客网站搜索出来的转换方法,效率是有的但不太灵活,还要继承实现工具类提供的方法,感觉太麻烦,我就想要把数据集转换为树结构你还要我继承实现一个类,疯了吧

废话不多说上代码


import java.util.*;
import java.util.function.Function;

public class ToTreeUtil<T,K> {
    private final List<T> list;
    private final Function<? super T, ? extends K> getId;
    private final Function<? super T, ? extends K> getParentId;
    private final Function<T, List<T>> getChildren;
    private final Consumer<T> setChildren;

    /**
     *
     * @param list 需要转换的list数据
     * @param getId 节点的id
     * @param getParentId 节点的父id
     * @param getChildren 注入子节点的方法
     */
    public ToTreeUtil(List<T> list,
                      Function<? super T, ? extends K> getId,
                      Function<? super T, ? extends K> getParentId, Function<T, List<T>> getChildren,Consumer<T> setChildren){
        this.list = list;
        this.getId = getId;
        this.getParentId = getParentId;
        this.getChildren = getChildren;
        this.setChildren = setChildren;
    }

    public List<T> buildNew() {
        if (this.list.isEmpty()) {
            return null;
        }
        // 使用HashMap来快速查找父节点
        Map<K, T> nodeMap = new HashMap<>();
        for (T node : this.list) {
            nodeMap.put(getId.apply(node),node);
        }
        List<T> rootNodes = new ArrayList<>();
        // 遍历所有节点,构建树结构
        for (T node : this.list) {
            //根节点
            if (getParentId.apply(node) == null || getParentId.apply(node).toString().equals("0") || getParentId.apply(node).toString().equals("")) {
                rootNodes.add(node);
            } else {
                T parentNode = nodeMap.get(getParentId.apply(node));
                List<T> children = getChildren.apply(parentNode);
                if(children==null){
                    children=new ArrayList<T>();
                    setChildren.accept(parentNode,children);
                }
                getChildren.apply(parentNode).add(node);
            }
        }
        return rootNodes;
    }
    public List<T> buildNew(Function<? super T, ? extends Object> getSeq,boolean isAsc) {
        if (this.list.isEmpty()) {
            return null;
        }
        // 使用HashMap来快速查找父节点
        Map<K, T> nodeMap = new HashMap<>();
        for (T node : this.list) {
            nodeMap.put(getId.apply(node),node);
        }
        List<T> rootNodes = new ArrayList<>();
        // 遍历所有节点,构建树结构
        for (T node : this.list) {
            //根节点
            if (getParentId.apply(node) == null || getParentId.apply(node).toString().equals("0") || getParentId.apply(node).toString().equals("")) {
                rootNodes.add(node);
            } else {
                T parentNode = nodeMap.get(getParentId.apply(node));
                List<T> children = getChildren.apply(parentNode);
                if(children==null){
                    children=new ArrayList<T>();
                    setChildren.accept(parentNode,children);
                }
                getChildren.apply(parentNode).add(node);
            }
        }
        //排序
        for (T rootNode : rootNodes) {
            this.sortChildren(rootNode,getSeq,isAsc);
        }
        return rootNodes;
    }

    /**
     * 排序子节点
     */
    public void sortChildren(T parent, Function<? super T, ? extends Object> getSeq,boolean isAsc) {
        List<T> children = getChildren.apply(parent);
        if(children==null || children.isEmpty()){
            return;
        }
        // 方法三:通过类型推断增强lambda表达式
        if(isAsc){
            // 使用匿名比较器排序
            Collections.sort(children, new Comparator<T>() {
                @Override
                public int compare(T p1, T p2) {
                    return new Double(getSeq.apply(p1).toString()).compareTo(new Double(getSeq.apply(p2).toString()));
                }
            });
        }else{
            // 使用匿名比较器排序
            Collections.sort(children, new Comparator<T>() {
                @Override
                public int compare(T p1, T p2) {
                    return new Double(getSeq.apply(p2).toString()).compareTo(new Double(getSeq.apply(p1).toString()));
                }
            });
        }
        setChildren.accept(parent,children);
        for (T child : children) {
            // 递归排序子节点的子节点
            sortChildren(child,getSeq,isAsc);
        }
    }

    public static void main(String[] args) {
        //测试样例
        List<Dept> userList=new ArrayList<>();
        //转换为组织树
        ToTreeUtil<Dept, Long> treeUtil = new ToTreeUtil<>(userList, Dept::getId, Dept::getParentId, Dept::getChildren, Dept::setChildren);
        //排序
        List<Dept> tree = treeUtil.buildNew(Dept::getSeq,true);
        //不要排序
        List<Dept> tree = treeUtil.buildNew();
    }
}

有不足的请指出,感觉还有优化的空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值