linkedhashset通过哈希表+双向链表实现o(1)去重与插入顺序维护,底层基于linkedhashmap,元素作key、present作value;add时重复则忽略,首次插入追加链表尾;遍历严格按首次插入顺序。

LinkedHashSet 通过哈希表 + 双向链表的组合结构,既利用哈希表实现 O(1) 的唯一性检查,又用链表记录插入顺序。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
底层结构:哈希表负责去重,链表负责记顺序
LinkedHashSet 本身不存储数据,而是内部持有一个 LinkedHashMap 实例。每个元素作为 key 存入 LinkedHashMap 中,value 固定为一个静态的 PRESSENT 对象(无实际意义)。
LinkedHashMap 的特性是:
- 底层用哈希表快速定位 key,保证 add()、contains() 等操作平均时间复杂度为 O(1),自然支持唯一性;
- 同时维护一条双向链表,按元素首次插入的顺序串联所有 key 节点,从而保留插入序。
添加元素时自动处理重复和顺序
调用 add(e) 时:
- 如果元素 e 已存在(map.containsKey(e) 返回 true),则不插入,也不改变链表结构;
- 如果不存在,则执行 map.put(e, PRESENT),LinkedHashMap 会把新节点追加到链表尾部,并更新哈希桶引用。
这意味着:相同元素多次 add,只有第一次生效,且顺序只由首次插入位置决定。
遍历时严格按插入顺序返回
因为迭代器基于 LinkedHashMap 的链表结构实现,所以:
- for-each、iterator()、stream() 都从头节点开始,沿链表 next 指针依次访问;
- 删除某个元素后,链表会调整前后指针,后续遍历跳过该节点,其余顺序不变;
- 注意:LinkedHashSet 不支持随机访问或按索引取值,它不是 List。
使用建议与注意事项
- 若只需去重不要顺序,用 HashSet 内存更省、稍快;
- 若既要顺序又要频繁按索引查,考虑先用 LinkedHashSet 去重,再转成 ArrayList;
- 插入顺序指「首次成功添加」的顺序,不是调用 add() 的次数顺序;
- 线程不安全,多线程写入需外部同步,例如用 Collections.synchronizedSet(new LinkedHashSet())。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










