java 迭代器的深入分析

遇到一个问题,怎么对一个集合实现双重遍历的过程中进行元素的筛选删除?
刚开始的思路是使用迭代器之后再在中间使用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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值