只读集合

创建集合后,它们就是可读写的,否则就不能给他们填充值了。但是,在填充完集合后,可以创建只读集合。

List<T>集合的AsReadOnly()方法返回ReadOnlyCollection<T>类型的对象。ReadOnlyCollection<T>类实现的接口与List<T>集合相同,但所有修改集合的方法和属性都抛出NotSupportedException异常。除了List<T>的接口之外,ReadOnlyCollection<T>还实现了IReadOnlyCollection<T>和IReadOnlyList<T>接口。因为这些接口的成员,集合不能修改。

<think> 我们正在讨论Java中创建只读Map集合的方法。根据引用[1]和引用[2],我们可以总结出以下几种方法: 1. 使用Collections.unmodifiableMap()(Java 9之前) 2. 使用Map.of()和Map.ofEntries()(Java 9引入) 3. 使用Map.copyOf()(Java 10引入) 另外,引用[3]中也提到Map的创建和操作方法,但主要是关于可修改的Map。我们需要关注的是如何创建只读(不可修改)的Map。 因此,回答将围绕以上三种创建只读Map的方式展开,包括它们的特性、用法和区别。 </think> ### Java 创建只读 Map 集合的完整指南 #### 一、Java 9+ 推荐方案 1. **`Map.of()` 工厂方法** 适用于小型固定键值对(最多 10 个): ```java Map<String, Integer> readOnlyMap = Map.of( "Java", 17, "Python", 3, "Go", 1 ); ``` - ✅ **特性**:完全不可变、禁止 `null` 键值、空间优化 - ❗ **限制**:最多 10 个键值对(超限需用 `Map.ofEntries()`) 2. **`Map.ofEntries()` 工厂方法** 处理任意数量键值对: ```java Map<String, Integer> map = Map.ofEntries( Map.entry("Java", 17), Map.entry("Python", 3), Map.entry("Go", 1), Map.entry("Rust", 2015) ); ``` - ✅ **优势**:支持超过 10 个元素、语法更清晰 - ️ **注意**:需配合 `Map.entry()` 构建键值对 3. **`Map.copyOf()` 防御性复制** 转换现有 Map 为只读副本: ```java Map<String, Integer> modifiableMap = new HashMap<>(); modifiableMap.put("Java", 17); Map<String, Integer> readOnlyMap = Map.copyOf(modifiableMap); // 创建独立不可变副本 ``` - ✅ **场景**:保护原始数据不被修改[^2] - ⚠️ **注意**:深拷贝键值对象引用(浅不可变) --- #### 二、Java 8 及以下兼容方案 1. **`Collections.unmodifiableMap()`** ```java Map<String, Integer> modifiableMap = new HashMap<>(); modifiableMap.put("Java", 8); Map<String, Integer> readOnlyMap = Collections.unmodifiableMap(modifiableMap); ``` - ✅ **兼容性**:支持 Java 1.2+ - ⚠️ **注意事项**: - 是原始 Map 的**视图**(原始 Map 修改会影响视图) - 允许 `null` 键值 - 需额外内存存储包装器 2. **Guava 不可变集合(第三方库)** ```java ImmutableMap<String, Integer> readOnlyMap = ImmutableMap.of("Java", 8, "Python", 3); ``` - ✅ **优势**:更丰富的构建器 API、性能优化 - ❗ **依赖**:需引入 `com.google.guava:guava` --- #### 三、核心特性对比 | **特性** | `Map.of()`/`Map.ofEntries()` | `Map.copyOf()` | `Collections.unmodifiableMap()` | |------------------------|------------------------------|------------------------|---------------------------------| | **不可变性** | ✅ 完全独立不可变 | ✅ 完全独立不可变 | ❌ 原始 Map 的视图 | | **null 支持** | ❌ 禁止 null 键值 | ❌ 禁止 null 键值 | ✅ 允许 null | | **元素数量限制** | `Map.of()` ≤10 | 无限制 | 无限制 | | **内存占用** | 空间优化存储 | 独立副本 | 包装器开销 | | **Java 版本** | 9+ | 10+ | 1.2+ | --- #### 四、使用示例与验证 ```java // 创建只读 Map Map<String, Integer> map = Map.of("A", 1, "B", 2); // 验证不可变性 map.put("C", 3); // 抛出 UnsupportedOperationException map.remove("A"); // 抛出 UnsupportedOperationException // 防御性编程示例 public Map<String, Integer> getConfig() { Map<String, Integer> config = loadConfigFromDB(); return Map.copyOf(config); // 返回不可变副本 } ``` > **关键原则**:优先使用 Java 9+ 的 `Map.of()`/`Map.copyOf()`,兼顾安全性与性能;兼容旧系统时选择 `Collections.unmodifiableMap()` 或 Guava[^1][^2]。 --- ### 补充说明 1. **浅不可变性(Shallow Immutability)** 只读 Map **仅保证容器结构不可变**,若值对象是可变类(如 `ArrayList`),其内部状态仍可修改: ```java Map<String, List<String>> map = Map.of("Data", new ArrayList<>()); map.get("Data").add("New"); // 允许修改值对象内容 ``` 2. **线程安全性** 所有只读 Map 实现均**天生线程安全**,无需额外同步。 3. **序列化** Java 9+ 的不可变 Map 支持优化序列化,反序列化后仍保持不可变特性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值