Java 集合--快速掌握涵盖三大场景实现的Set集合底层原理
Java 集合–快速掌握涵盖三大场景实现的Set集合底层原理引言在 Java 集合框架中Set接口是一个不允许包含重复元素的集合。与List不同Set没有索引概念元素存取无序。虽然Set看似简单但其底层实现却涉及多种数据结构以适应不同场景的需求。本文将深入剖析HashSet、TreeSet和LinkedHashSet这三大经典实现的底层原理并通过实战代码演示帮助开发者快速掌握其核心机制。—## 一、HashSet基于哈希表的快速查找### 1.1 底层数据结构HashSet底层实际上是一个HashMap的实例。当我们向HashSet添加元素时实际上是将该元素作为HashMap的 key 存入而 value 则是一个固定的常量对象PRESENT。这种设计使得HashSet能充分利用HashMap的哈希算法实现 O(1) 时间复杂度的增删改查。### 1.2 哈希冲突处理当两个不同的元素通过hashCode()计算得到相同的哈希桶索引时就会发生哈希冲突。HashSet采用链地址法数组链表/红黑树来解决冲突当链表长度超过阈值默认为8且数组长度大于64时链表会转换为红黑树以提升查找性能。### 1.3 实战代码示例javaimport java.util.HashSet;import java.util.HashMap;public class HashSetDemo { public static void main(String[] args) { // 创建HashSet实例 HashSetString set new HashSet(); // 添加元素 set.add(Apple); set.add(Banana); set.add(Cherry); set.add(Apple); // 重复元素不会添加成功 // 输出集合大小 System.out.println(集合大小: set.size()); // 输出 3 // 检查元素是否存在 System.out.println(包含Apple? set.contains(Apple)); // true // 遍历集合无序 for (String fruit : set) { System.out.println(水果: fruit); } // 底层原理验证HashSet实际上是一个HashMap // 通过反射获取内部map try { java.lang.reflect.Field mapField HashSet.class.getDeclaredField(map); mapField.setAccessible(true); HashMapString, Object internalMap (HashMapString, Object) mapField.get(set); System.out.println(内部HashMap容量: internalMap.size()); // 3 } catch (Exception e) { e.printStackTrace(); } }}输出说明由于HashSet基于哈希表元素输出顺序与插入顺序无关且重复元素被自动过滤。—## 二、TreeSet基于红黑树的有序集合### 2.1 底层数据结构TreeSet底层是一个TreeMap红黑树结构它要求元素必须实现Comparable接口或者在构造时传入一个Comparator比较器。红黑树是一种自平衡的二叉搜索树能够保证所有操作增删改查的时间复杂度为 O(log n)并且元素会按照自然顺序或比较器定义的顺序排序。### 2.2 排序机制TreeSet在插入元素时会通过红黑树的节点比较逻辑确定元素位置。如果自定义对象未实现Comparable且未提供比较器则会抛出ClassCastException。### 2.3 实战代码示例javaimport java.util.TreeSet;import java.util.Comparator;public class TreeSetDemo { public static void main(String[] args) { // 创建一个按字母逆序排序的TreeSet TreeSetString treeSet new TreeSet(Comparator.reverseOrder()); treeSet.add(Charlie); treeSet.add(Alice); treeSet.add(Bob); treeSet.add(David); // 输出有序集合逆序 System.out.println(逆序排序结果:); for (String name : treeSet) { System.out.println(name); // David, Charlie, Bob, Alice } // 使用自定义对象必须实现Comparable TreeSetPerson personSet new TreeSet(); personSet.add(new Person(张三, 25)); personSet.add(new Person(李四, 30)); personSet.add(new Person(王五, 20)); System.out.println(\n按年龄排序的人员:); for (Person p : personSet) { System.out.println(p); } // 获取第一个和最后一个元素 System.out.println(最年轻的人: personSet.first()); // 王五 System.out.println(最年长的人: personSet.last()); // 李四 }}// 自定义Person类实现Comparable接口class Person implements ComparablePerson { private String name; private int age; public Person(String name, int age) { this.name name; this.age age; } Override public int compareTo(Person other) { // 按年龄升序排序 return this.age - other.age; } Override public String toString() { return name ( age 岁); }}关键点TreeSet通过红黑树维护元素顺序自定义对象必须提供比较逻辑否则无法正常工作。—## 三、LinkedHashSet结合哈希表与双向链表### 3.1 底层数据结构LinkedHashSet继承自HashSet但其内部使用LinkedHashMap而不是普通的HashMap。LinkedHashMap在HashMap的基础上增加了一个双向链表用于维护元素的插入顺序或访问顺序。因此LinkedHashSet既能保证元素的唯一性通过哈希表又能保持迭代顺序与插入顺序一致。### 3.2 性能特点-插入性能接近HashSet的 O(1) 时间复杂度但维护链表会带来额外的内存开销。-迭代性能由于链表的存在LinkedHashSet的迭代速度通常比HashSet更快因为它只需要遍历链表而HashSet需要遍历整个哈希桶数组。### 3.3 实战代码示例javaimport java.util.LinkedHashSet;public class LinkedHashSetDemo { public static void main(String[] args) { // 创建LinkedHashSet LinkedHashSetString linkedSet new LinkedHashSet(); // 添加元素 linkedSet.add(第一); linkedSet.add(第二); linkedSet.add(第三); linkedSet.add(第二); // 重复不会添加 // 输出结果保持插入顺序 System.out.println(LinkedHashSet遍历保持插入顺序:); for (String item : linkedSet) { System.out.println(item); } // 输出: 第一, 第二, 第三 // 对比HashSet无序 java.util.HashSetString hashSet new java.util.HashSet(); hashSet.add(第一); hashSet.add(第二); hashSet.add(第三); System.out.println(\nHashSet遍历无序:); for (String item : hashSet) { System.out.println(item); } // 性能测试插入大量数据 long startTime System.nanoTime(); LinkedHashSetInteger largeLinkedSet new LinkedHashSet(); for (int i 0; i 100000; i) { largeLinkedSet.add(i); } long endTime System.nanoTime(); System.out.println(\nLinkedHashSet插入10万元素耗时: (endTime - startTime) / 1_000_000 ms); }}运行结果分析LinkedHashSet保证了元素的插入顺序而HashSet则完全无序。虽然维护链表会稍有性能损耗但在大多数场景下可以忽略不计。—## 四、三大Set实现对比总结| 特性 | HashSet | TreeSet | LinkedHashSet ||------|---------|---------|---------------|| 底层结构 | HashMap数组链表/红黑树 | TreeMap红黑树 | LinkedHashMapHashMap双向链表 || 元素顺序 | 无序 | 自然顺序或自定义顺序 | 插入顺序 || 时间复杂度 | O(1) 平均 | O(log n) | O(1) 平均 || 是否允许null | 允许一个null | 不允许需比较 | 允许一个null || 适用场景 | 快速查找、去重 | 需要排序的集合 | 需要保持插入顺序且去重 |—## 五、选择指南-追求极致性能选择HashSet适合大数据量且不关心顺序的场景。-需要自动排序选择TreeSet适合需要范围查询或有序遍历的场景如排行榜。-需要保持插入顺序选择LinkedHashSet适合需要记录操作顺序的去重场景如最近访问记录。—## 总结本文通过大量实战代码演示深入分析了HashSet、TreeSet和LinkedHashSet的底层实现原理。HashSet基于哈希表实现快速查找TreeSet基于红黑树实现自动排序LinkedHashSet则通过哈希表与双向链表的结合在保持元素唯一性的同时维护了插入顺序。理解这些底层机制有助于我们在实际开发中根据具体场景选择最合适的Set实现从而优化程序性能和代码可读性。记住没有绝对的最优只有最适合场景的选择。

相关新闻

Visual Studio远程开发Linux C++项目:配置、调试与实战指南

Visual Studio远程开发Linux C++项目:配置、调试与实战指南

1. 项目概述:为什么要在Windows上用VS搞Linux开发?如果你是一个长期在Windows环境下使用Visual Studio(后面简称VS)的C开发者,现在因为项目需求,必须将代码部署到Linux服务器上运行,那你大概率会…

2026/10/11 7:54:44 阅读更多 →
Testwell CTC++ 10.1.0:ASPICE认证下的代码覆盖率分析与CI/CD集成实践

Testwell CTC++ 10.1.0:ASPICE认证下的代码覆盖率分析与CI/CD集成实践

1. 项目概述:当ASPICE遇上新版CTC 最近在软件测试圈子里,Testwell CTC 10.1.0的发布算是个不大不小的新闻。对于像我这样常年和嵌入式、汽车电子软件打交道的测试工程师来说,这不仅仅是一个工具的版本迭代,更像是一个明确的信号&a…

2026/10/11 8:52:11 阅读更多 →
中文汉化 Claude

中文汉化 Claude

点击地址:https://github.com/javaht/claude-desktop-zh-cn/tree/main 下载压缩包后解压找到install-windows.bat双击运行 一直按1回车1运行就行,完成后会自动重启claude桌面版,接下来就可以使用了,关于skills,多技能后面再进行介…

2026/10/11 8:52:02 阅读更多 →

最新新闻

广工操作系统实验:Linux内核模块实操指南

广工操作系统实验:Linux内核模块实操指南

简介:本资源是广东工业大学操作系统课程配套的完整实验实践包,面向计算机专业本科生及操作系统初学者,聚焦进程调度、作业调度、主存管理与文件系统四大核心模块,助力理解内核级机制并提升系统编程能力。压缩包共12个文件&#xf…

2026/10/11 13:57:13 阅读更多 →
一文看懂 Open Event Theme:eventyay 开源活动平台标准主题的来龙去脉

一文看懂 Open Event Theme:eventyay 开源活动平台标准主题的来龙去脉

【免费下载链接】open-event-theme Open Event Standard Theme http://next.eventyay.com 项目地址: https://gitcode.com/gh_mirrors/op/open-event-theme 点击查看 免费下载 Open Event Theme 是开源活动平台 eventyay(Open Event)的标准主…

2026/10/11 13:57:13 阅读更多 →
MySQL data文件夹迁移实操:Windows与Linux避坑指南

MySQL data文件夹迁移实操:Windows与Linux避坑指南

简介:MySQL数据库的data文件夹默认位于/var/lib/mysql,当系统盘空间紧张、数据安全性要求提升或需要将存储调整到独立分区时,迁移数据目录便成为运维人员常遇的任务。这份PDF指南围绕此类场景,提供了从关闭Apache与MySQL服务、使用…

2026/10/11 13:57:13 阅读更多 →
基于Spring Boot与Hadoop的高校体育健康大数据管理系统设计

基于Spring Boot与Hadoop的高校体育健康大数据管理系统设计

这个选题有意思,是把传统的高校体育信息化管理系统,往大数据分布式计算的方向上推了一把。标题里几个关键词我都拆开看了——Spring Boot、Hadoop、体质监测、运动干预、设施调度,每一个单拎出来都是常见选题,但它们组合在一起&am…

2026/10/11 13:57:13 阅读更多 →
拼团旅游平台毕业设计:Spring Boot核心架构与拼团状态机实战解析

拼团旅游平台毕业设计:Spring Boot核心架构与拼团状态机实战解析

1. 项目概述 1.1 核心需求解析 拼团式旅游服务平台,名字听起来挺长,拆开看其实就两个关键词:拼团、旅游。拼团是社交电商里非常成熟的玩法——几个人凑成一个团,以低于单人价的价格拿下同一个商品或服务。旅游则是把这种玩法移植…

2026/10/11 13:57:13 阅读更多 →
关键词URL采集工具实战:从乱码链接中高效提取与去重

关键词URL采集工具实战:从乱码链接中高效提取与去重

简介:关键词URL采集工具是一套面向SEO优化、市场调研与数据挖掘从业者的自动化网址搜集方案,核心用途是依据指定关键词批量抓取搜索引擎结果页中的匹配链接,替代人工逐页翻找,降低时间成本。资源包共4个文件,以rar格式…

2026/10/11 13:56:13 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →