最近在项目中遍历删除List时遇到了java.lang.UnsupportedOperationException: remove的异常。由于代码写的比较多,查了半天才发现,原来是由于使用了Arrays.asList()函数导致的。大概相当于是这么写的:
List<Integer> list = Arrays.asList(1,2,3,4,5);
Iterator<Integer> iters = list.iterator();
while(iters.hasNext()) {
int i = iters.next();
if(i == 1) {
iters.remove();
}
}
执行这段代码就会出现java.lang.UnsupportedOperationException: remove的异常提示。而使用ArrayList则没有问题,如下这么写:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> iters = list.iterator();
while(iters.hasNext()) {
int i = iters.next();
if(i == 1) {
iters.remove();
}
}
如果觉得上述写的比较麻烦,那么可以这么写
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
Iterator<Integer> iters = list.iterator();
while(iters.hasNext()) {
int i = iters.next();
if(i == 1) {
iters.remove();
}
}
我用的是jdk14,可以发现Iterator接口中remove方法是这么写的:
default void remove() {
throw new UnsupportedOperationException("remove");
}
也就是说调用remove方法,默认就是要抛出这个异常的。在使用debug的时候会发现,调用Arrays.asList()方法时,Iterator的这个时候实现类是Arrays$ArrayItr,ArrayItr是Arrays私有静态内部类,里面并未重写remove方法,而调用ArrayList构造方法创建的List,Iterator这个时候的实现类是ArrayList$Itr,Itr是ArrayList的私有内部类,Itr类中重写了remove方法。
因此,如果在遍历List时候删除,应该避免使用Arrays.asList()方法来构建List。
参考:
- https://blog.csdn.net/zysen1995/article/details/90415339
- https://blog.csdn.net/lin451791119/article/details/82705557