最近在迭代中删除List中的元素时遇到UnsupportedOperationException,印象中如果程序写错的时候是报ConcurrentModificationException,具体场景及原因如下:

一、问题及解决方法

1、代码

其中部分代码省略,只保留出错代码。

public static void main(String[] args) {
	//实际中方法会接收一个字符串类型的参数
	String idStr = "1,2,3,4,5";
	//转为List是为了后续方便处理
	List<String> ids = Arrays.asList(idStr.split(","));
	Iterator<String> iterator = ids.iterator();
	while(iterator.hasNext()){
		if("3".equals(iterator.next())){
			iterator.remove();
			break;
		}
	}
}

运行此方法,报错:

2、解决方法

String[]转为List时不要使用Arrays.asList()方法,而是自己创建java.util.ArrayList对象,再遍历数组将元素添加到此List中。

String idStr = "1,2,3,4,5";
List<String> ids = new ArrayList<>();
for(String id : idStr.split(",")){
	ids.add(id);
}
...

3、原因

由于Arrays.asList()方法中返回的是java.util.Arrays.ArrayList<E>,此处的ArrayListArrays的内部类,它继承自java.util.AbstractList<E>,但没有重写remove()方法,而AbstractListremove()方法中是直接抛出了UnsupportedOperationException异常。

  • ArraysArrays.ArrayList

  • java.util.AbstractList.remove(int)
public E remove(int index) {
	throw new UnsupportedOperationException();
}

二、List迭代删除元素的两种方式

1、使用迭代器删除

List<String> items = new ArrayList<>();
items.add("ax");
items.add("by");
items.add("cx");
items.add("dz");

Iterator<String> iterator = items.iterator();
while(iterator.hasNext()){
	if(iterator.next().indexOf('x') > -1){
		iterator.remove();
	}
}

System.out.println(items);

2、倒序迭代删除

List<String> items = new ArrayList<>();
items.add("ax");
items.add("by");
items.add("cx");
items.add("dz");

for(int i = items.size() - 1; i > -1; i--){
	if(items.get(i).indexOf('x') > -1){
		items.remove(i);
	}
}

System.out.println(items);