《Java工程师必读手册》——Java编程技巧系列——Java编程技巧之数据结构(1)

简介: 《Java工程师必读手册》——Java编程技巧系列——Java编程技巧之数据结构(1)

导读

 

唐宋八大家之一欧阳修在《卖油翁》中写道:

 

| 翁取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿。因曰:“我亦无他,唯手熟尔。”

 

编写代码的老司机也是如此,老司机之所以被称为老司机”,原因也是无他,唯手熟尔。编码过程中踩过的坑多了,获得的编码经验也就多了,总结的编码技巧也就更多了。总结的编码技巧多了,凡事又能够举一反三,编码的速度自然就上来了。笔者从数据结构的角度,整理了一些Java编程技巧,以供大家学习参考。


一、 使用HashSet判断主键是否存在

 

HashSet实现Set接口,由哈希表(实际上是HashMap)实现,但不保证set的迭代顺序,并允许使用null元素。HashSet的时间复杂度跟HashMap一致,如果没有哈希冲突则时间复杂度为O1,如果存在哈希冲突则时间复杂度不超过On。所以,在日常编码中,可以使用HashSet判断主键是否存在。

 

案例

 

给定一个字符串不一定全为字母,请返回第一个重复出现的字符。

 

image.png

 

其中,由于Set的add函数有个特性——如果添加的元素已经再集合中存在,则会返回false。可以简化代码为:

 

image.png

 

二、 使用HashMap存取键值映射关系

 

简单来说,HashMap由数组和链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。如果定位到的数组位置不含链表,那么查找、添加等操作很快,仅需一次寻址即可,其时间复杂度为O1;如果定位到的数组包含链表,对于添加操作,其时间复杂度为On——首先遍历链表,存在即覆盖,不存在则新增;对于查找操作来讲,仍需要遍历链表,然后通过key对象的equals方法逐一对比查找。从性能上考虑,HashMap中的链表出现越少,即哈希冲突越少,性能也就越好。所以,在日常编码中,可以使用HashMap存取键值映射关系。

 

案例

 

给定菜单记录列表,每条菜单记录中包含父菜单标识(根菜单的父菜单标识为null),构建出整个菜单树。

 

/** 菜单DO类 */

@Setter

@Getter

@ToString

public static class MenuDO {

    /** 菜单标识 */

    private Long id;

    /** 菜单父标识 */

    private Long parentId;

    /** 菜单名称 */

    private String name;

    /** 菜单链接 */

    private String url;

}

 

/** 菜单VO类 */

@Setter

@Getter

@ToString

public static class MenuVO {

    /** 菜单标识 */

    private Long id;

    /** 菜单名称 */

    private String name;

    /** 菜单链接 */

    private String url;

    /** 子菜单列表 */

    private List<MenuVO> childList;

}

 

/** 构建菜单树函数 */

public static List<MenuVO> buildMenuTree(List<MenuDO> menuList) {

    // 检查列表为空

    if (CollectionUtils.isEmpty(menuList)) {

        return Collections.emptyList();

    }

 

    // 依次处理菜单

    int menuSize = menuList.size();

    List<MenuVO> rootList = new ArrayList<>(menuSize);

    Map<Long, MenuVO> menuMap = new HashMap<>(menuSize);

    for (MenuDO menuDO : menuList) {

        // 赋值菜单对象

        Long menuId = menuDO.getId();

        MenuVO menu = menuMap.get(menuId);

        if (Objects.isNull(menu)) {

            menu = new MenuVO();

            menu.setChildList(new ArrayList<>());

            menuMap.put(menuId, menu);

        }

        menu.setId(menuDO.getId());

        menu.setName(menuDO.getName());

        menu.setUrl(menuDO.getUrl());

 

        // 根据父标识处理

        Long parentId = menuDO.getParentId();

        if (Objects.nonNull(parentId)) {

            // 构建父菜单对象

            MenuVO parentMenu = menuMap.get(parentId);

            if (Objects.isNull(parentMenu)) {

                parentMenu = new MenuVO();

                parentMenu.setId(parentId);

                parentMenu.setChildList(new ArrayList<>());

                menuMap.put(parentId, parentMenu);

            }

            

            // 添加子菜单对象

            parentMenu.getChildList().add(menu);

        } else {

            // 添加根菜单对象

            rootList.add(menu);

        }

    }

 

    // 返回根菜单列表

    return rootList;

}

 

 接下篇:https://developer.aliyun.com/article/1228149?groupCode=java

相关文章
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
656 1
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
1349 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
325 2
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
358 2
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
214 1
|
搜索推荐 算法 Java
2025 年互联网大厂校园招聘 JAVA 工程师笔试题及备考要点解析
本文针对互联网大厂校招Java工程师笔试题进行解析,涵盖基础知识、面向对象编程、数据结构与算法、异常处理及集合框架等核心内容。从数据类型、运算符到流程控制语句,从类与对象、继承多态到数组链表、排序算法,再到异常捕获与集合框架应用,结合实际案例深入剖析,助你系统掌握考点,提升应试能力。资源链接:[点此获取](https://pan.quark.cn/s/14fcf913bae6)。
413 9
|
Java 数据库连接 API
互联网大厂校招 JAVA 工程师笔试题解析及常见考点分析
本文深入解析互联网大厂校招Java工程师笔试题,涵盖基础知识(数据类型、流程控制)、面向对象编程(类与对象、继承与多态)、数据结构与算法(数组、链表、排序算法)、异常处理、集合框架、Java 8+新特性(Lambda表达式、Stream API)、多线程与并发、IO与NIO、数据库操作(JDBC、ORM框架MyBatis)及Spring框架基础(IoC、DI、AOP)。通过技术方案讲解与实例演示,助你掌握核心考点,提升解题能力。
479 2
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
537 3
|
存储 Java 编译器
Java 中 .length 的使用方法:深入理解 Java 数据结构中的长度获取机制
本文深入解析了 Java 中 `.length` 的使用方法及其在不同数据结构中的应用。对于数组,通过 `.length` 属性获取元素数量;字符串则使用 `.length()` 方法计算字符数;集合类如 `ArrayList` 采用 `.size()` 方法统计元素个数。此外,基本数据类型和包装类不支持长度属性。掌握这些区别,有助于开发者避免常见错误,提升代码质量。
1124 1

热门文章

最新文章