遇到一个问题,怎么对一个集合实现双重遍历的过程中进行元素的筛选删除?
刚开始的思路是使用迭代器之后再在中间使用for-each语句,但是经查阅资料发现
如果要对JAVA集合进行遍历删除时必须用迭代器
比如这段代码
参考http://blog.51cto.com/guojuanjun/1348450
public static void main(String args[]) {
List<String> famous = new ArrayList<String>();
famous.add("liudehua");
famous.add("madehua");
famous.add("liushishi");
famous.add("tangwei");
for (String s : famous) {
if (s.equals("madehua")) {
famous.remove(s);
}
}
}
查阅这篇博客可以知道,java在for-each语句中其实用的时迭代器操作,ArrayList与Iterator混合使用时会导致各自的状态出现不一样,最终出现异常。看一下AbstractList中的源码
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
在这里,元素下标从0开始,cursor初始指向第一个元素,只要cursor小于表的长度,hasnext返回true.
每调用一次next方法,cursor加1,lastret指向上一次返回的元素下标
可以看到这里通过checkForComodification进行检查,如果是这个迭代器以外的操作进行remove
会报错
最后不可以声明两个迭代器,也会抛出上述错误
package adf.sample.util;
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String args[])
{
ArrayList list = new ArrayList();
list.add(5);
list.add(3);
list.add(2);
Iterator it = list.iterator();
Iterator it2 = list.iterator();
System.out.println(it.next());
it.remove();
it2.remove();
System.out.println(it2.next());
}
}
“`
5
Exception in thread “main” java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:872)
at Test.main(Test.java:15)