Arrays.asList() 不能用其修改方法

引语

阿里巴巴java开发规范说到使用工具类Arrays.asList()方法把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException(),我们来看一下为什么会出现这种情况.

问题分析

我们做个测试

public static void main(String[] args) {
List list = Arrays.asList(“a”, “b”, “c”);
// list.clear();
// list.remove(“a”);
// list.add(“g”);
}
被注释的三行可以分别解开注释,运行后确实出现了规约中所说的异常.我们来看下Arrays.asList()做了什么操作.

public static List asList(T… a) {
return new ArrayList<>(a);
}
看上去是个很正常的方法,然而实际上你点进到ArrayList发现,其实ArrayList并不是我们平时用的ArrayList.

private static class ArrayList extends AbstractList
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings(“unchecked”)
public T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// 后面省略了
而是Arrays里面的一个内部类.而且这个内部类没有add,clear,remove方法,所以抛出的异常其实来自于AbstractList.

public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
点进去就会发现抛出异常的地方,clear底层也会调用到remove所以也会抛出异常.

总结

1.Arrays.asList()不要乱用,底层其实还是数组;

2.如果使用了Arrays.asList()的话,最好不要使用其集合的操作方法;

3.List list = new ArrayList<>(Arrays.asList(“a”, “b”, “c”))可以在外面这样包一层真正的ArrayList(数组转集合有很多方式,可以参考https://stackoverflow.com/questions/157944/create-arraylist-from-array).

### Arrays.asList() 返回的列表不可修改的原因 `Arrays.asList()` 方法返回的列表实际上是 `java.util.Arrays` 类中的一个内部类 `ArrayList` 的实例,而不是我们通常使用的 `java.util.ArrayList`。这个内部类 `ArrayList` 继承自 `AbstractList`,并且没有实现 `add()` 和 `remove()` 方法[^1]。因此,当尝试对通过 `Arrays.asList()` 创建的列表调用 `add()` 方法时,会抛出 `UnsupportedOperationException` 异常。 此外,`Arrays.asList()` 返回的列表是一个固定大小的视图,其底层数据结构仍然是传入的数组。任何对列表的操作都会直接影响到原始数组,但无法改变列表的大小[^4]。 --- ### 解决方案 为了使列表能够动态调整大小并支持 `add()` 和 `remove()` 操作,可以将 `Arrays.asList()` 返回的列表包装到一个真正的 `java.util.ArrayList` 实例中。以下是具体的实现方式: ```java import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { String[] array = {"apple", "banana", "cherry"}; // 使用 Arrays.asList() 返回固定大小的列表 List<String> fixedSizeList = Arrays.asList(array); // 将固定大小的列表转换为可变大小的 ArrayList List<String> mutableList = new ArrayList<>(fixedSizeList); // 现在可以使用 add() 方法 mutableList.add("orange"); System.out.println(mutableList); // 输出: [apple, banana, cherry, orange] } } ``` 在这个例子中,`Arrays.asList(array)` 返回的是一个固定大小的列表,而通过 `new ArrayList<>(fixedSizeList)` 创建了一个新的、可变大小的 `ArrayList`,从而支持了 `add()` 和 `remove()` 操作[^3]。 --- ### 注意事项 1. 如果需要对基本数据类型(如 `int[]`, `double[]`)使用类似的功能,则需要先将其转换为对应的包装类数组(如 `Integer[]`, `Double[]`),因为 `Arrays.asList()` 不支持直接处理基本数据类型数组[^4]。 2. 在某些情况下,如果只需要读取操作而不涉及修改列表大小,可以直接使用 `Arrays.asList()` 返回的列表,以避免额外的内存开销。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值