当前位置: 首页 > news >正文

Java Set 集合深度解析(HashSet / TreeSet 原理详解)

一、什么是 Set

在 Java 集合框架中,Set 是一个不允许重复元素的集合

特点:

  1. 元素唯一

  2. 无索引

  3. 部分实现类无序

示例:

Set<String> set = new HashSet<>(); set.add("Java"); set.add("Python"); set.add("Java"); System.out.println(set);

输出:

[Java, Python]

说明:

Set 自动去重

二、Set 集合体系结构

Java Set 结构:

Collection │ └── Set │ ├── HashSet │ └── LinkedHashSet │ └── SortedSet │ └── TreeSet

常见实现类:

特点
HashSet无序、不重复
LinkedHashSet有序、不重复
TreeSet排序、不重复

三、HashSet 原理(重点)

HashSet 本质:

HashSet = HashMap

源码:

private transient HashMap<E,Object> map;

HashSet 存储结构:

key -> element value -> 固定对象

源码:

private static final Object PRESENT = new Object();

add 方法:

public boolean add(E e) { return map.put(e, PRESENT) == null; }

结构示意:

HashMap │ key value Java -> PRESENT Python-> PRESENT C++ -> PRESENT

所以:

HashSet 底层完全依赖 HashMap

四、HashSet 数据结构

HashSet 的底层结构就是HashMap

即:

数组 + 链表 + 红黑树

结构:

table │ ├── Node -> Node │ ├── Node -> Node -> Node │ └── Node -> 红黑树

因此:

HashSet 的性能 ≈ HashMap

五、HashSet 去重原理

Set 之所以不允许重复,核心依赖:

hashCode() equals()

执行流程:

add(element) │ 计算 hashCode │ 定位数组位置 │ 是否存在元素 │ equals 判断

流程图:

hashCode 相同 │ equals 判断 │ │ true false │ │ 不插入 插入

示例

class Student{ int id; String name; }

如果不重写:

equals hashCode

结果:

不会去重

因为:

地址不同

必须重写:

@Override public int hashCode() { return Objects.hash(id,name); } @Override public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof Student)) return false; Student s = (Student)obj; return id == s.id && Objects.equals(name,s.name); }

六、LinkedHashSet 原理

LinkedHashSet 是:

HashSet 子类

源码:

public class LinkedHashSet<E> extends HashSet<E>

底层:

LinkedHashMap

结构:

Hash表 + 双向链表

示意:

HashMap │ 双向链表维护顺序

结构:

A → B → C → D

特点:

保持插入顺序

示例:

Set<String> set = new LinkedHashSet<>(); set.add("C"); set.add("A"); set.add("B"); System.out.println(set);

输出:

[C, A, B]

顺序保持。


七、TreeSet 原理

TreeSet 特点:

自动排序

底层:

TreeMap

源码:

private transient NavigableMap<E,Object> m;

数据结构:

红黑树

示意:

10 / \ 5 15 / \ 3 7

时间复杂度:

O(log n)

八、TreeSet 排序规则

TreeSet 排序方式有两种:

1 自然排序

对象实现:

Comparable

示例:

class Student implements Comparable<Student>{ int age; @Override public int compareTo(Student o){ return this.age - o.age; } }

TreeSet:

Set<Student> set = new TreeSet<>();

2 自定义排序

使用:

Comparator

示例:

Set<Student> set = new TreeSet<>( (a,b)->a.age - b.age );

九、HashSet vs LinkedHashSet vs TreeSet

集合底层结构是否有序时间复杂度
HashSetHashMap无序O(1)
LinkedHashSetLinkedHashMap插入顺序O(1)
TreeSet红黑树排序O(log n)

选择建议:

需要去重 → HashSet 需要顺序 → LinkedHashSet 需要排序 → TreeSet

十、Set 常用方法

add(E e) remove(Object o) contains(Object o) size() clear()

示例:

Set<String> set = new HashSet<>(); set.add("Java"); set.remove("Java"); set.contains("Java");

十一、Set 遍历方式

Set 没有索引,因此不能:

for(i)

遍历方式:

增强for

for(String s:set){ System.out.println(s); }

Iterator

Iterator<String> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); }

forEach

set.forEach(System.out::println);

十二、Set 为什么没有 get()

原因:

Set 无索引

Set 设计理念:

只关心元素存在

而不是:

位置

十三、Set 面试高频问题

1 HashSet 底层结构

HashMap

2 HashSet 如何去重

依赖:

hashCode equals

3 HashSet 是否有序

无序

4 LinkedHashSet 为什么有序

因为:

双向链表

维护:

插入顺序

5 TreeSet 为什么能排序

因为底层:

红黑树

6 TreeSet 插入复杂度

O(log n)

7 TreeSet 为什么不能存 null

因为排序需要:

compareTo

null 无法比较。


十四、总结

Java Set 核心结构:

Set │ ├─ HashSet │ HashMap │ ├─ LinkedHashSet │ LinkedHashMap │ └─ TreeSet 红黑树

核心知识:

HashSet去重原理 LinkedHashSet顺序 TreeSet排序 hashCode + equals 红黑树
http://www.jsqmd.com/news/483941/

相关文章:

  • 【AI】OpenClaw 祛魅教程 | 面向普通人的 AI 入门指南
  • Git 、TortoiseGit 安装使用教程
  • MySQL 事务隔离级别
  • 【2026年蚂蚁春招-算法岗 - 3月15日 -第三题- 最小字符串】(题目+思路+JavaC++Python解析+在线测试)
  • 基于Spring Boot的乡村信息管理系统设计与实践
  • 基于 Spring AI 构建多智能体协作系统(高级版)
  • 智慧养殖鱼类病害的自动识别与分类 助水产养殖从业者及时诊断鱼病 鱼类疾病识别数据集 鱼类养殖检测数据集第10561期
  • 基于SpringBoot+Vue的热门文创文创内容推荐平台
  • Every Day of a DBA,第123期: ASM 磁盘发现oracleasm-discover
  • ARM Cortex‑M带U大介绍,内核都带啥U!
  • 算法工程中的内存访问模式优化研究的技术7
  • 古装微短剧《嘉庆君游台湾》开机 霍政谚全力以赴演绎永琰
  • XTUOJ众数(前缀和,窗口滑动)
  • 力扣算法刷题 Day 10
  • Spring框架(1):从入门到精通全解析
  • 知识点总结三
  • 传统芯片设计vs AI驱动:AI应用架构师的效率之战,选对路很重要
  • wwoshiAT caishao
  • Could not create connection to database server. Attempted reconnect 3 times. Giving up.
  • 基于嵌入式的数据库SQLite
  • Kingbase 彻底卸载+重装全流程(保姆级)
  • 深度学习-线性回归模型解析
  • lerobot中openpi0模型的processor示例
  • 基于SpringBoot的运动服装销售系统设计与实现
  • 大数据领域Spark的数据存储与读取方式
  • 忘记密码怎么办?教程来了!!!(包会)
  • 《Azul报告:62%的Java开发者已在写AI代码,这5个Java+AI实战场景你必须会》
  • PFM和FCCM的区别是什么?
  • 高效查重工具评测:9大方案助力论文质量提升
  • 3月16日直播丨面向新一代硬件,CANN技术架构的变与不变