前因
在实际开发中我使用Arrays.asList 将一个字符串数组转化为List使用,后续需要根据规则判断从该List中移除元素 但是移除的时候出现了错误java.lang.UnsupportedOperationException
String[] strs = {"小A","小B","小C"};
List<String> stringList = Arrays.asList(strs);
stringList.remove("小A");
错误:throw java.lang.UnsupportedOperationException
探索
- 查询Arrays.asList的定义
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
翻译:返回了一个定长的List,这个方法用于转化array系列API与collection系列API,返回值仅仅是数组简单包装而成的List而已,并不能直接修改其长度。
Think In java的解释
It’s also possible to use the output of Arrays.asList( ) directly, as a List, but the
underlying representation in this case is the array, which cannot be resized. If you try to
add( ) or delete( ) elements in such a list, that would attempt to change the size of an array,
so you’ll get an "Unsupported Operation" error at run time.
注意: 这里返回的是new ArrayList,我们平时定义的List list = new ArrayList();为何平时定义的ArrayList可以add和remove这里不可以呢? 是因为这里的new ArrayList其实是Arrays内部自己实现的一个内部类
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
也就是说
- Arrays.asList返回的ArrayList 实际上是Arrays的内部类 属于java.util.Arrays$ArrayList
- List list = new ArrayList 属于java.util.ArraysList 查询ArrayList源码后发现他并没有实现add和remove方法,因此再向上一层查看AbstractList的源码
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
因此抛出了java.lang.UnsupportedOperationException
至此就了解了为什么Arrays.asList()转化后的List无法add和remove
解决办法
使用new ArrayList<>(Arrays.asList())
示例:List list = new ArrayList<>(Arrays.asList(1,2,3));
总结
1.Arrays.asList返回的是一个定长数组不能add和remove(结论),add和remove会返回java.lang.UnsupportedOperationException
2.Arrays.asList返回的ArrayList 不是真的ArrayList 而是AbstractList中的一个内部类 AbstractList的add和remove方法throw java.lang.UnsupportedOperationException(原因),真正的ArrayList继承了AbstractList,并实现了add和remove方法
3.解决方法:使用new ArrayList<>(Arrays.asList())
示例:List list = new ArrayList<>(Arrays.asList(1,2,3));