LinkedHashSet 是 Java 中既能去重又能保持插入顺序的 Set 实现,底层基于 LinkedHashMap,通过哈希表实现 O(1) 去重、双向链表维护插入顺序,允许一个 null,非线程安全,适用于需“先到先得”语义的场景。

LinkedHashSet 是 Java 中既能去重又能保持插入顺序的 Set 实现,底层基于 LinkedHashMap,因此它天然支持按元素添加顺序迭代,同时继承了 HashSet 的高效去重能力(平均 O(1) 时间复杂度)。
为什么 LinkedHashSet 能兼顾有序和去重
LinkedHashSet 内部维护了一个双向链表 + 哈希表的组合结构:哈希表负责快速判断元素是否存在(实现去重),双向链表记录元素插入的先后顺序(实现迭代有序)。这使得它在 add、contains、remove 等操作上既快又稳定,且遍历时顺序始终与插入一致。
基本用法:声明、添加、遍历
使用方式与普通 Set 一致,只需指定泛型并用 LinkedHashSet 实例化:
- 声明并初始化:Set<String> set = new LinkedHashSet<>();
- 添加元素(重复添加自动忽略):set.add("apple"); set.add("banana"); set.add("apple"); // 第二个 apple 不生效
- 遍历时顺序固定:for (String s : set) { System.out.println(s); } // 输出:apple → banana(按首次插入顺序)
注意 null 元素和线程安全
LinkedHashSet 允许存储一个 null 元素(因为底层 LinkedHashMap 支持 null key),但不允许多个 null;它本身不是线程安全的。如果多线程并发修改,需额外同步:
立即学习“Java免费学习笔记(深入)”;
- 简单加锁:Set<String> safeSet = Collections.synchronizedSet(new LinkedHashSet<>());
- 或使用并发替代方案(如 CopyOnWriteArraySet),但要注意其迭代快照特性和写性能开销较大,一般仅适用于读多写少场景。
对比其他 Set 实现的适用场景
当需求明确是“去重 + 插入顺序”时,LinkedHashSet 是最直接的选择:
- HashSet:去重快,但迭代顺序不可预测(取决于哈希值和扩容);
- TreeSet:按自然序或自定义序排序,但不是插入序,且增删查为 O(log n);
- LinkedHashSet:插入序 + 去重 + 接近 O(1) 性能,适合日志记录、缓存键追踪、UI 列表去重等需要“先到先得”语义的场景。


















