ArrayList循环遍历并删除元素的陷阱

版权声明:转载请注明出处 https://blog.csdn.net/yrwan95/article/details/82833398
import java.util.ArrayList;
public class ArrayListRemove {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("c");
		list.add("c");
		remove(list);

		for (String s : list) {
			System.out.println("element : " + s);
		}
	}

	public static void remove(ArrayList<String> list) {
		// TODO:
	}
}

错误写法实例一:for循环遍历list

public static void remove(ArrayList<String> list) {
	for (int i = 0; i < list.size(); i++) {
		if (list.get(i).equals("del"))
			list.remove(i);
	}
}

删除某个元素后,list的大小发生了变化,而索引也在变化,所以会导致在遍历的时候漏掉某些元素。比如当删除第1个元素后,继续根据索引访问第2个元素时,因为删除的关系后面的元素都往前移动了一位,所以实际访问的是第3个元素。因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。

解决方法: 从list最后一元素开始开始遍历。

public static void remove(ArrayList<String> list) {
	for (int i = list.size() - 1; i >= 0; i--) {
		if (list.get(i).equals("b"))
			list.remove(i);
	}
}

错误写法实例二:增强for循环

public static void remove(ArrayList<String> list) {
	for (String s : list) {
		if (s.equals("b")) {
			list.remove(s);
		}
	}
}

删除元素后继续循环会报错误信息ConcurrentModificationException,因为元素在使用的时候发生了并发的修改,导致异常抛出 解决:删除完毕马上使用break跳出,则不会触发报错。

public static void remove(ArrayList<String> list) {
	for (String s : list) {
		if (s.equals("b")) {
			list.remove(s);
			break;
		}
	}
}

错误写法实例三:iterator遍历

public static void remove(ArrayList<String> list) {
	Iterator<String> it = list.iterator();
	while (it.hasNext()) {
		String x = it.next();
		if (x.equals("b")) {
			it.remove();
		}
	}
}

这种方式可以正常的循环及删除。但要注意的是,使用iterator的remove方法,如果用list的remove方法同样会报上面提到的ConcurrentModificationException错误。

总结:

  1. 循环删除list中特定一个元素的,可以使用三种方式中的任意一种,但在使用中要注意上面分析的各个问题。
  2. 循环删除list中多个元素的,应该使用迭代器iterator方式,或者list从后往前删除。

猜你喜欢

转载自blog.csdn.net/yrwan95/article/details/82833398