linkedhashset通过哈希表+双向链表维持插入顺序:元素作为key存入linkedhashmap,value为pressent;add()首次插入才更新链表,重复添加不改变顺序;迭代按链表头到尾遍历,严格保持首次插入顺序。

LinkedHashSet 通过内部维护一个双向链表来保持元素的插入顺序。它本质上是 HashSet 的子类,底层使用 LinkedHashMap 实现,而 LinkedHashMap 在哈希表基础上额外用链表记录元素的插入顺序。
底层结构:哈希表 + 双向链表
LinkedHashSet 没有自己独立的存储结构,而是直接复用 LinkedHashMap 的实现:
- 每个元素作为 key 存入 LinkedHashMap,value 固定为一个静态的
PRESSENT对象(无实际意义) - 哈希表负责 O(1) 时间复杂度的查找和去重
- 双向链表按插入顺序串起所有节点,保证迭代时从头到尾依次访问
插入时自动更新链表
每次调用 add() 方法时:
- 先通过哈希计算确定桶位置,判断是否已存在(利用哈希表的唯一性)
- 若不存在,则新建节点,既插入哈希表,也追加到链表尾部
- 若已存在(重复元素),不新增节点,链表结构不变
因此,只有首次插入才影响顺序,重复添加不会改变已有顺序。
迭代过程只遍历链表
调用 iterator() 返回的是 LinkedHashMap 的有序迭代器:
- 它不按哈希桶顺序,而是从链表头节点开始,沿
after指针逐个访问 - 所以
for-each或显式迭代器遍历的结果,严格等于元素第一次被添加的顺序
注意:不是访问顺序,也不支持自定义排序
LinkedHashSet 默认保持的是插入顺序,不是最近访问顺序(那是 LinkedHashMap#accessOrder = true 的行为):
- 没有
get()方法,不触发“访问重排” - 不实现
SortedSet,不能像 TreeSet 那样按自然序或比较器排序 - 如果需要按访问顺序维护,需自行用 LinkedHashMap 模拟;如需排序,应选 TreeSet
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











