Java中HashSet本身可变,不可变需借助工具:Collections.unmodifiableSet()提供只读视图(不复制数据),Set.of()(Java 9+)创建真正不可变副本,Guava的ImmutableSet支持null和大容量,手动封装不推荐。

Java 中 HashSet 本身是可变集合,不能直接“实现”不可变集合;但可以通过包装或转换方式获得一个**不可修改的视图**或**真正不可变的副本**。关键在于:不可变性不是 HashSet 的内置特性,而是通过工具类或新 API 提供的保障。
使用 Collections.unmodifiableSet()
这是最常用的方式,返回原 HashSet 的只读视图。注意:它不复制数据,底层仍引用原集合;若原集合被意外修改,视图也会反映变化(只是无法通过该视图修改)。
示例:
Set<String> mutable = new HashSet<>(Arrays.asList("a", "b", "c"));
Set<String> immutableView = Collections.unmodifiableSet(mutable);
immutableView.add("d"); // 抛出 UnsupportedOperationException
mutable.add("d"); // ✅ 允许 —— 视图会“看到”这个变化!
使用 Set.of()(Java 9+)创建真正不可变集合
这是推荐方式:它创建的是紧凑、高效、线程安全且**完全不可变**的集合(底层非 HashSet 实现,但行为等价)。不接受 null,元素数量有限制(最多 10 个),适合静态常量场景。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
示例:
Set<String> immutable = Set.of("a", "b", "c");
immutable.add("d"); // 编译通过?不,运行时抛出 UnsupportedOperationException
// 且:即使原集合被改,它也不受影响 —— 它是独立实例
使用 Guava 的 ImmutableSet(第三方库)
适合需要更多灵活性的场景(如支持 null、大容量、构建器模式)。它在创建时深拷贝元素,确保彻底不可变,且性能优化良好。
示例:
Set<String> immutable = ImmutableSet.of("a", "b", "c");
// 或从已有 set 构建
Set<String> fromHashSet = ImmutableSet.copyOf(new HashSet<>(Arrays.asList("x", "y")));
手动封装(不推荐,仅作理解)
可自定义包装类,重写所有修改方法并抛异常。但易出错、无泛型安全保证、不享受 JVM 优化,实际项目中应避免。
- 需覆盖
add、remove、clear、retainAll等全部 mutator 方法 - 仍需确保构造时复制元素,否则外部仍可修改原始引用
- 无法阻止子类绕过限制,安全性弱于标准库方案

















