Java 高效构建树形结构

这篇具有很好参考价值的文章主要介绍了Java 高效构建树形结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java 高效构建树形结构

构造树形结构通常使用递归遍历元素,构造元素的子集,直至子级全部构建完成,返回父级,最终完成树的构建,这种方法的时间复杂度基本上在 O ( N 2 ) O(N^2) O(N2),数据量比较大的时候性能大幅下降,耗时严重。通过不断实践与优化,得出一种可将构造树形结构的性能提升,时间复杂度能至 O ( N ) O(N) O(N)的方法。

方法说明:
  1. 将集合按父级id分组,得到父级id为key,子级元素集合为value的map;
  2. 遍历原集合,以元素id为key获取map中的子级集合,将子级集合放入父级元素中
  3. 返回最上层元素,即为树形结构数据
特点:

● 使用stream并行流,提高效率
● 通过对象地址引用实现父子级关联,即使父级先添加了子级,子级在添加孙子级,父子孙三级也全部都会关联

代码:
	import cn.hutool.core.collection.CollUtil;
	import cn.hutool.core.lang.Assert;

	/**
     * 构造数据树 O(N)
     *
     * @param list           原集合
     * @param mKey           父级被子集关联的字段,比如id
     * @param treeConnectKey 子集关联父级的字段,比如parentId
     * @param treeSortKey    同级菜单的排序字段,比如sort
     * @param consumer       添加子集的函数,如dto.setChild(list)
     * @param <M>
     * @return
     */
    public static <M> List<M> buildTree(List<M> list, Function<M, ?> mKey, Function<M, ?> treeConnectKey,
                                        Function<M, ? extends Comparable> treeSortKey, Consumers<M, M> consumer) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Assert.notNull(mKey, "父级被子级关联的字段不能为空");
        Assert.notNull(treeConnectKey, "子级关联父级的字段不能为空");
        Assert.notNull(consumer, "消费函数不能为空");
        //线程安全类集合
        List<M> tree = Collections.synchronizedList(new ArrayList<>());
        //按上级id分组
        final Map<?, List<M>> collect = list.parallelStream().collect(Collectors.groupingBy(treeConnectKey));
        list.parallelStream().filter(m -> {
            final boolean b = (Long) treeConnectKey.apply(m) != 0L;
            if (!b) {
                tree.add(m);
            }
            return b;
        }).forEach(
                //通过对象地址引用实现父子级关联,即使父级先添加了子级,子级在添加孙子级,父子孙三级也全部都会关联
                m -> {
                    if (treeSortKey != null) {
                        consumer.accept(m, CollUtil.sort(collect.get(mKey.apply(m)), java.util.Comparator.comparing(treeSortKey)));
                    } else {
                        consumer.accept(m, collect.get(mKey.apply(m)));
                    }
                }
        );
        if (treeSortKey != null) {
            //排序
            tree.sort(java.util.Comparator.comparing(treeSortKey));
            return tree.parallelStream().peek(b -> consumer.accept(b, CollUtil.sort(collect.get(mKey.apply(b)), java.util.Comparator.comparing(treeSortKey)))).collect(Collectors.toList());
        } else {
            return tree.parallelStream().peek(b -> consumer.accept(b, collect.get(mKey.apply(b)))).collect(Collectors.toList());
        }
    }

    @FunctionalInterface
    public interface Consumers<M, N> {

        /**
         * 消费函数
         *
         * @param m
         * @param n
         */
        void accept(M m, List<N> n);
    }
}

调用:

import lombok.Getter;
import lombok.Setter;
import java.util.List;

/**
 * 部门
 */
@Getter
@Setter
public class DeptDTO {

    private Long id;

    /**
     * 上级部门
     */
    private Long parentId;

    /**
     * 部门名称
     */
    private String deptName;

    /**
     * 部门编码
     */
    private String deptCode;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 子部门
     */
    private List<DeptDTO> child;
}
//模拟原始数据
final List<DeptDTO> dtos = new ArrayList<>();
//获取树结构
List<DeptDTO> tree = TreeUtil.buildTree(dtos, DeptDTO::getId, DeptDTO::getParentId, DeptDTO::getCreateTime, DeptDTO::setChild);

表述不正确之处欢迎指正,欢迎留言分享效率更高的方法!文章来源地址https://www.toymoban.com/news/detail-561712.html

到了这里,关于Java 高效构建树形结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java返回前端树形结构数据(2种实现方式)

    0.思想 首先找到一级目录(类别),然后从一级目录(类别)递归获取所有子目录(类别),并组合成为一个“目录树” 1.普通实现:controller层传的是0层,就是一级目录层,从这里开始往下递归。 2.stream流实现: 3.实体类集合专VO类集合的工具类 入参为未知类型的实体集合

    2024年02月04日
    浏览(35)
  • 组合模式:构建灵活的树形结构

    组合模式(Composite Pattern)是一种广泛应用于软件开发中的设计模式,旨在通过树形结构来表示对象的部分-整体层次。这种模式允许用户以一致的方式处理单个对象和对象组合,从而简化了复杂结构的处理过程。在本文中,我们将通过Java语言的例子来详细探讨组合模式的概念

    2024年04月10日
    浏览(26)
  • 高效构建Java应用:Maven入门和进阶

    1.1 Maven介绍 https://maven.apache.org/what-is-maven.html Maven 是一款为 Java 项目构建管理、依赖管理的工具( 软件 ),使用 Maven 可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。 总结:Maven就是一个软件,掌握软件安装、配置、以及基本功能**(项目构建、依赖

    2024年02月02日
    浏览(38)
  • 使用Docker构建高效的Java微服务

    在当今的软件开发领域,Docker 和 Java 微服务结合使用,成为了提升应用部署、扩展和管理效率的重要方式。本文将深入探讨如何使用 Docker 构建高效的 Java 微服务,包括详细的代码示例和注释。 一、Docker 和 Java 微服务的基本概念 1、Docker 简介 Docker 是一个开源的应用容器引擎

    2024年02月03日
    浏览(37)
  • 高效构建Java应用:Maven入门和进阶(一)

    1.1 Maven介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具( 软件 ),使用 Maven 可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。 总结:Maven就是一个软件,掌握软件安装、配置、以及基本功能 (项目构建、依赖管理) 使用就是本课程的主要目标

    2024年01月25日
    浏览(73)
  • 高效构建Java应用:Maven入门和进阶(二)

    2.1 梳理Maven工程GAVP属性 Maven工程相对之前的工程,多出一组gavp属性,gav需要我们在创建项目的时指定,p有默认值,后期通过配置文件修改。既然要填写的属性,我们先行了解下这组属性的含义! Maven 中的 GAVP 是指 GroupId、ArtifactId、Version、Packaging 等四个属性的缩写,其中前三

    2024年02月01日
    浏览(46)
  • 一、高效构建Java应用:Maven入门和进阶

    一、Maven简介和快速入门 1.1 Maven介绍 1.2 Maven主要作用理解 1.3 Maven安装和配置 二、基于IDEA的Maven工程创建 2.1梳理Maven工程GAVP属性 2.2 Idea构建Maven JavaSE工程 2.3 Idea构建Maven JavaEE工程 2.4 Maven工程项目结构说明 三、Maven核心功能依赖和构建管理 3.1 依赖管理和配置 3.2依赖传递和冲

    2024年02月08日
    浏览(38)
  • 高效构建Java应用:Maven入门和进阶(五)

    5.1 项目需求和结构分析 需求案例:搭建一个电商平台项目,该平台包括用户服务、订单服务、通用工具模块等。 项目架构: 用户服务:负责处理用户相关的逻辑,例如用户信息的管理、用户注册、登录等。 订单服务:负责处理订单相关的逻辑,例如订单的创建、订单支付

    2024年01月19日
    浏览(37)
  • Spring Boot的魔法:构建高效Java应用的秘诀

    🎉欢迎来到架构设计专栏~Spring Boot的魔法:构建高效Java应用的秘诀 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,

    2024年02月08日
    浏览(49)
  • 使用Maven容器打包Java项目:一步步实现高效构建

    在Java开发中,使用Maven作为构建工具是一个普遍的选择。它提供了简单易用的方式来管理依赖、编译代码、运行单元测试并打包项目。本文将详细介绍如何使用Maven容器打包Java项目,让您的项目构建过程更加高效和可靠。 在开始之前,请确保您已经安装了Maven和Docker,并设置

    2024年02月13日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包