一个数组转成list,调用remove
,add
方法报 UnsupportedOperationException
,样例如下:
import java.util.Arrays;
import java.util.List;
/**
* @author lfg1991@qq.com
* @create 2017-04-27 13:53
**/
public class ArraysDemo {
public static void main(String[] args) {
String[] str = {"5", "7", "8"};
List list = Arrays.asList(str);
list.remove(0); //UnsupportedOperationException
System.out.println(list);
System.out.println(Arrays.toString(str));
}
}
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at me.douwo.ArraysDemo.main(ArraysDemo.java:18)
原因: Arrays内部有个静态ArrayList类继承了AbstractList
,但是并没有重写 add、remove 方法,Arrays.asList采用内部ArrayList类new的对象,add、remove调用的是父类AbstractList中的方法,父类并没有真正的实现。
Arrays.asList 源码
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
...
java.util.AbstractList 源码
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
Arrays.asList 返回的是一个list,但是内部实际上是一个定长数组,不能增、删,可以修改,修改会改变原始数组,原始数组和内部数组是同一个。见源码:
private final E[] a;
ArrayList(E[] array) {
if (array==null)
throw new NullPointerException();
a = array;
}
所以Arrays.asList 最好作为只读的list使用,解决方法就是使用 正经的ArrayList
List list = new ArrayList(Arrays.asList(str));