java.lang.UnsupportedOperationException at java.util.AbstractList

本文详细介绍了在Java开发中,使用Arrays.asList()后调用add,remove等方法时出现UnsupportedOperationException异常的问题原因及解决办法。通过使用Iterator或转换为ArrayList,可以有效解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

找到这个bug的原因和解决方法了,共享下....


『Java』 java.lang.UnsupportedOperationException at java.util.AbstractList

常常使用Arrays.asLisvt()后调用add,remove这些method时出现 java.lang.UnsupportedOperationException异常。这是由于:

Arrays.asLisvt() 返回java.util.Arrays$ArrayList, 而不是ArrayList。Arrays$ArrayList和ArrayList都是继承AbstractList,remove,add等 method在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。ArrayList override这些method来对list进行操作,但是Arrays$ArrayList没有override remove(int),add(int)等,所以throw UnsupportedOperationException。

解决方法是使用Iterator,或者转换为ArrayList

  1. List list = Arrays.asList(a[]);  
  2. List arrayList = new ArrayList(list); 

原出处:


http://blog.youkuaiyun.com/chao121/article/details/5604263
<think>我们正在处理的是 `java.lang.UnsupportedOperationException` 错误。根据引用内容,这个异常通常发生在尝试修改一个不可变的集合时。具体来说,当我们使用 `Arrays.asList()` 方法将数组转换为列表后,得到的列表是固定大小的(不支持添加或删除操作),调用 `add()` 或 `remove()` 等方法就会抛出此异常。 ### 错误原因分析 1. **不可变集合操作**:通过 `Arrays.asList()` 返回的列表是 `Arrays` 的内部类 `ArrayList`,它继承自 `AbstractList` 但没有重写 `add()` 和 `remove()` 等方法。因此,当调用这些方法时,实际上调用的是 `AbstractList` 中的默认实现,即直接抛出 `UnsupportedOperationException`[^4][^5]。 2. **常见触发场景**: - 尝试向 `Arrays.asList()` 返回的列表中添加元素(`add()` 方法) - 尝试从中删除元素(`remove()` 方法) - 其他修改操作(如 `clear()`) ### 解决方案 #### 方法1:创建新的 `ArrayList` 对象 将 `Arrays.asList()` 返回的列表作为参数传递给一个新的 `ArrayList` 对象,这样得到的列表就是可变的。 ```java List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); list.add("d"); // 现在可以正常添加 ``` #### 方法2:使用 Java 8 的 Stream API(适用于 Java 8 及以上) ```java List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList()); list.add("d"); // 正常 ``` #### 方法3:使用 Collections 工具类(不常用) ```java List<String> list = new ArrayList<>(); Collections.addAll(list, "a", "b", "c"); list.add("d"); // 正常 ``` ### 示例代码对比 #### 错误代码 ```java List<String> list = Arrays.asList("a", "b", "c"); list.add("d"); // 抛出 UnsupportedOperationException ``` #### 正确代码 ```java // 方法1 List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); list.add("d"); // 成功 // 方法2(Java 8+) List<String> list = new ArrayList<>(Stream.of("a", "b", "c").collect(Collectors.toList())); list.add("d"); // 方法3 List<String> list = new ArrayList<>(); Collections.addAll(list, "a", "b", "c"); list.add("d"); ``` ### 关键点总结 | **操作** | **Arrays.asList() 返回的列表** | **new ArrayList<>() 创建的列表** | |------------------|--------------------------------|----------------------------------| | 支持添加元素 | ❌ 抛出异常 | ✅ 允许 | | 支持删除元素 | ❌ 抛出异常 | ✅ 允许 | | 支持修改元素 | ✅ (通过 `set` 方法) | ✅ 允许 | | 数据结构是否可变 | 固定大小(不可变) | 动态大小(可变) | > **注意**:`Arrays.asList()` 返回的列表虽然不可变,但支持通过 `set(index, element)` 修改已有位置的元素[^5]。 --- §§相关问题§§ 1. 如何正确初始化一个可变的字符串列表? 2. Java 中哪些集合操作会抛出 `UnsupportedOperationException`? 3. 如何将数组转换为可修改的列表? 4. Java 集合框架中哪些集合是不可变的? [^1]: [java.lang.UnsupportedOperationException 的解决方法【转】](引用链接1) [^2]: [java.lang.UnsupportedOperationException问题分析及解决](引用链接2) [^3]: [java.lang.UnsupportedOperationException解决方法](引用链接3) [^4]: [报错:java.lang.UnsupportedOperationException 原因](引用链接4) [^5]: [java.lang.UnsupportedOperationException报错如何解决](引用链接5)</think>### 分析 `java.lang.UnsupportedOperationException` 报错原因及解决方案 #### **根本原因分析** 该异常通常发生在尝试修改**不可变集合**时,核心原因是底层集合实现未重写修改方法(如 `add()`, `remove()` 等)。具体场景: 1. **使用 `Arrays.asList()` 创建的集合**(最常见原因) ```java List<String> list = Arrays.asList("A", "B", "C"); // 返回 Arrays$ArrayList list.add("D"); // 抛出 UnsupportedOperationException ``` - `Arrays.asList()` 返回的是 `Arrays` 内部类 `ArrayList`,它继承自 `AbstractList` 但**未重写 `add()/remove()` 方法**[^4][^5] - `AbstractList` 的默认实现是直接抛出异常: ```java public void add(int index, E element) { throw new UnsupportedOperationException(); } ``` 2. **其他不可变集合操作** - 通过 `Collections.unmodifiableList()` 创建的只读集合 - `List.of()` 创建的不可变集合(Java 9+) - 尝试修改 `Map.keySet()` 或 `Map.values()` 等视图集合 --- #### **解决方案** ##### 方案1:创建真正的可变集合(推荐) ```java // 使用标准 ArrayList 包装 List<String> mutableList = new ArrayList<>(Arrays.asList("A", "B", "C")); mutableList.add("D"); // ✅ 正常执行 ``` ##### 方案2:使用 Java 8+ 的流式 API ```java List<String> list = Stream.of("A", "B", "C") .collect(Collectors.toList()); // 返回可变 ArrayList list.add("D"); // ✅ ``` ##### 方案3:需要修改集合视图时 ```java Map<String, Integer> map = new HashMap<>(); map.put("A", 1); // 错误:直接修改 keySet 视图 // Set<String> keys = map.keySet(); // keys.remove("A"); // ❌ 抛出异常 // 正确:创建新集合 Set<String> keys = new HashSet<>(map.keySet()); keys.remove("A"); // ✅ ``` --- #### **关键区别:两种 ArrayList** | **特性** | `java.util.ArrayList` | `Arrays$ArrayList` (内部类) | |------------------------|-------------------------------|----------------------------------| | 所在包 | `java.util` | `java.util.Arrays` | | 是否可修改 | ✅ 支持 add/remove | ❌ 固定大小 | | 继承关系 | 重写 `AbstractList` 所有方法 | 未重写 `add()/remove()` 方法[^5] | | 内存结构 | 动态数组 | 直接包装原始数组 | | 适用场景 | 常规可变集合 | 临时只读视图 | --- #### **最佳实践** 1. **明确集合的可变性**: ```java // 只读集合(明确声明) List<String> readOnly = Collections.unmodifiableList(Arrays.asList("A", "B")); // 可变集合(显式创建) List<String> mutable = new ArrayList<>(readOnly); ``` 2. **避免直接操作**: - 不要直接修改 `Arrays.asList()`, `List.of()`, `Collections.singletonList()` 的返回值 - 需要修改时先通过构造函数复制 3. **使用现代 API**(Java 9+): ```java List<String> mutable = new ArrayList<>(List.of("A", "B")); // 安全复制 ``` > 📌 **调试提示**:遇到此异常时,检查集合的运行时类型(`list.getClass().getName()`),若为 `java.util.Arrays$ArrayList` 则说明问题根源在此[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值