JAVA集合元素的迭代删除

        在Java中有时候我们会需要对List里面的符合某种业务的数据进行删除,但是如果不了解里面的机制就容易掉入“陷阱”导致遗漏或者程序异常。下面发表一下我自己的经验:

1、采用索引下标遍历的方式

import java.util.ArrayList;

public class TestList {

	public static void main(String[] args) {
		
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(2);
		list.add(3);
		list.add(4);
		
		//这里是把这个集合中元素是2的删除掉
		for (int i = 0; i < list.size(); i++) {
			if( 2==list.get(i) ){
				list.remove(i);
			}
		}
		
		System.out.println("最后list中剩余的元素是:"+list);    //[1, 2, 3, 4]
	}
}

        可见最后的结果并不是我们想要的结果,到底为什么呢?

         原因是:删除了第一个2后,集合里的元素个数减1,后面的元素往前移了1位,导致了第二个2被遗漏了。

2、采用for...each循环遍历的方式

import java.util.ArrayList;

public class TestList {

	public static void main(String[] args) {
		
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(2);
		list.add(3);
		list.add(4);
		
		for (Integer i : list) {
			if( i==2 ){
				list.remove(i);
			}
		}
		
		System.out.println(list);
	}
}
运行结果:
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at forTest.TestList.main(TestList.java:16)

看见程序抛ConcurrentModificationException异常。

这又是为什么呢?

        原因是:Java中的For each实际上使用的是iterator进行处理的。而iterator是不允许集合在iterator使用期间删除的。所以导致了iterator抛出了ConcurrentModificationException 


3、在遍历 list 过程中删除元素的正确做法

import java.util.ArrayList;
import java.util.Iterator;

public class TestList {

	public static void main(String[] args) {
		
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(2);
		list.add(3);
		list.add(4);
		
		Iterator<Integer> iter = list.iterator();
		while(iter.hasNext()){
			Integer i = iter.next();
			if( i==2 ){
				iter.remove();
			}
		}
		System.out.println(list);        //[1, 3, 4]
	}
}

这样就不会出错了。记得用 Iterator 中的remove 方法,不用用list中的remove 

但对于iterator的remove()方法,也有需要我们注意的地方:

1、每调用一次iterator.next()方法,只能调用一次remove()方法。

2、调用remove()方法前,必须调用过一次next()方法。


以下是JDK-API中对于remove()方法的描述:

void remove()

从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的集合,则迭代器的行为是不明确的。

抛出:UnsupportedOperationException - 如果迭代器不支持 remove 操作。IllegalStateException - 如果尚未调用 next 方法,或者在上一次调用 next 方法之后已经调用了remove 方法。

本文出自 “专注Java,linux技术” 博客,请务必保留此出处http://wuqinglong.blog.51cto.com/9087037/1558499

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。