Java生成部门树形结构,使用HashMap空间换时间,时间复杂度O(n)

还在使用递归生成树形结构?太慢!使用HashMap用空间换时间,一次遍历即可构建树形结构。后面将使用泛型和函数式编程优化,完成一个通用的树形结构生成工具。

public class TreeTest {
    public static void main(String[] args) {
        // 构建测试数据
        List<Dept> depts = generateDepts();

        long start = System.currentTimeMillis();

        List<Dept> topDepts = new ArrayList<>();
        Map<String, List<Dept>> map = new HashMap<>();

        for (Dept dept : depts) {
            // 构建自己的子部门列表
            String id = dept.getId();
            if (!map.containsKey(id)) {
                map.put(id, new ArrayList<>());
            }
            dept.setChildren(map.get(id));

            // 把自己加到父部门的子部门列表
            String pid = dept.getPid();
            if (!map.containsKey(pid)) {
                map.put(pid, new ArrayList<>());
            }
            map.get(pid).add(dept);

            // 顶级部门放到列表中
            if (dept.getPid() == null) {
                topDepts.add(dept);
            }
        }

        long end = System.currentTimeMillis();
        System.out.println(end - start);

    }

    private static List<Dept> generateDepts() {
        // 生成层级有5,每一层20个部门的部门列表,顶级部门的pid约定为null
        List<Dept> depts = generateDepts(20, 5, null);
        // 打乱列表的数据
        Collections.shuffle(depts);
        return depts;
    }

    private static List<Dept> generateDepts(int num, int d, String pid) {
        if (d == 0) {
            return Collections.emptyList();
        }
        List<Dept> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            String id = UUID.randomUUID().toString();
            list.add(new Dept(id, pid));
            // 递归生成以当前id为pid的子部门列表
            list.addAll(generateDepts(num, d - 1, id));
        }
        return list;
    }


    public static class Dept {
        private String id;
        private String pid;
        private List<Dept> children;

        public Dept(String id, String pid) {
            this.id = id;
            this.pid = pid;
        }

        public String getId() {
            return id;
        }

        public Dept setId(String id) {
            this.id = id;
            return this;
        }

        public String getPid() {
            return pid;
        }

        public Dept setPid(String pid) {
            this.pid = pid;
            return this;
        }

        public List<Dept> getChildren() {
            return children;
        }

        public Dept setChildren(List<Dept> children) {
            this.children = children;
            return this;
        }

        @Override
        public String toString() {
            return "Dept{" +
                    "id='" + id + '\'' +
                    ", pid='" + pid + '\'' +
                    ", children=" + children +
                    '}';
        }
    }
}

使用泛型和函数式编程优化,如下

    public static void main(String[] args) {
        // 构建测试数据
        List<Dept> depts = generateDepts();

        long start = System.currentTimeMillis();

        Function<Dept, String> getIdFunc = Dept::getId;
        Function<Dept, String> getPidFunc = Dept::getPid;
        BiConsumer<Dept, List<Dept>> setChildrenConsumer = Dept::setChildren;
        Predicate<Dept> isTopPred = dept -> Objects.isNull(dept.getPid());

        List<Dept> topList = generateTree(depts, getIdFunc, getPidFunc, setChildrenConsumer, isTopPred);

        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    public static  <T> List<T> generateTree(List<T> list,
                                            Function<T, String> getIdFunc,
                                            Function<T, String> getPidFunc,
                                            BiConsumer<T, List<T>> setChildrenConsumer,
                                            Predicate<T> isTopPred) {
        List<T> topList = new ArrayList<>();
        Map<String, List<T>> map = new HashMap<>();

        for (T obj : list) {
            // 构建自己的子列表
            String id = getIdFunc.apply(obj);
            if (!map.containsKey(id)) {
                map.put(id, new ArrayList<>());
            }
            setChildrenConsumer.accept(obj, map.get(id));

            // 把自己加到父对象的子列表
            String pid = getPidFunc.apply(obj);
            if (!map.containsKey(pid)) {
                map.put(pid, new ArrayList<>());
            }
            map.get(pid).add(obj);

            // 是否顶级
            if (isTopPred.test(obj)) {
                topList.add(obj);
            }
        }

        return topList;
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值