今天在做题,要实现遍历数组的时候同时删除指定元素,因为数组删除还要移动元素,所以就想Arrays.asList()转换成ArrayList使用迭代器删除。结果出现了java.lang.UnsupportedOperationException
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at reback_alg.alg_04.groupAnagrams1(alg_04.java:30)
at reback_alg.alg_04.main(alg_04.java:14)
先说解决办法吧!很简单就重新new一个java.util.ArrayList!
ArrayList list=new ArrayList(Arrays.asList(new int[]{1,2,3}));
之前看过《阿里巴巴java开发手册》记得有一条就是:使用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);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
1、方法的注释可看出,该方法作用是:传入指定的数组返回固定容量的list,提供了一个array到list的转换渠道。
2、方法返回的new ArrayList(a),而这个ArrayList其实是它的静态内部类,继承自AbastractList!
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
1、观察静态内部类的ArrayList常用的增删改方法发现它只重写了set(),并没有重写add()和remove(),而父类Abastract的这两个方法默认都是throw new UnsupportedOperationException(),
2、同时我们通过迭代器删除其实也是调用态内部类的ArrayList的remove()方法,因此就出现了文章开头的遇到的问题。
但是为什么要这么设计呢?为什么不直接使用java.util.ArrayList呢?
正如阿里巴巴的开发手册所说这体现适配器模式,只是一个转换接口,本质是还是一个数组。引用不变,如果原数组发生改变,转换后的List也会改变!
String[] strs = {"1", "2", "3"};
List<String> strs2 = Arrays.asList(strs);
//strs2的元素也会随之改变
strs[0]="0";