前言
在刷 leetcode 的时候,需要把一个数组转成一个list,并且需要往这个list中添加元素。很自然的就想到了 Arrays.asList() 这个方法。愉快的写出了下面的代码。
List<Integer> list = Arrays.asList(1);
list.add(2);
然而这个时候,异外出现了,抛出了异常 UnsupportedOperationException
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
原因分析
出错了,肯定要扒下是什么问题了,找到Arrays 的源码:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
这个方法很简单,就是创建了一个 ArrayList
,但是这个 ArrayList
不是我们常用的那个 java.util.ArrayList
,而是 Arrays
中的一个内部类。
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
}
这个内部类继承了 AbstractList
类,里面我们可以看到 add
方法的实现。
public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
真相出现了,其并没有实现新增元素,而是直接抛出了异常。
扩展
再扒下源码,其实,不仅无法使用 add
方法,也无法使用 set
、remove
等方法。
总结
这个问题在阿里巴巴开发手册中已经说明了。
【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { “you”, “wu” };
List list = Arrays.asList(str);
第一种情况:list.add(“yangguanbao”); 运行时异常。
第二种情况:str[0] = “gujin”; 那么 list.get(0)也会随之修改。