集合迭代器原理刨解JDK1.8(2)

1.ArrayList中的迭代器
ArrayList实现了迭代器接口,返回一个Itr内部类对象

   public Iterator<E> iterator() {
        return new Itr();
    }

2.Itr实现了Iterator接口,有个三个实例成员变量
首先理清楚foreach或获取Iterator跌代器对象,就用expectedModCount变量,
记录当前集合modCount变量的次数expectedModCount = modCount。
如果在遍历过程中,发现modCount != expectedModCount不相等,
说明用集合add或remove等方法,修改了当前集合元素,就报并发修改异常。

1.下一个要返回的元素位置

2.最后一个返回的索引位置,如果没有,返回-1

3.expectedModCount表示期望修改的次数,初始化外部类当前的修改次数modCount,
成员内部类可以直接访问外部类的实例变量,每次外部类modCount发生变化会增加,
迭代的时候,会比较expectedModCount和modCount是否相同,不相同会报异常。

4.checkForComodification()检查是否发生变化,没有发生变化。下面就更新cursorlastRet以及expectedModCount的值相同,返回元素对象

5.调用ArrayList的remove方法之前,同时更新上面第4点的值,所以能正确删除。调用remove删除方法之前必须next,不然会报错

List<Integer> list = new ArrayList<Integer>();
        list.add(22);
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
        		//iterator.next();
                iterator.remove();

Exception in thread “main” java.lang.IllegalStateException

protected transient int modCount = 0;

 private class Itr implements Iterator<E> {
        int cursor;       //1
        int lastRet = -1; //2
        int expectedModCount = modCount;//3

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification(); //4
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
	
        public void remove() { //5
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

检查方法

final void checkForComodification() {
  		//modCount变量修改次数和期望修改的次数不一样就报异常
            if (modCount != expectedModCount) 
                throw new ConcurrentModificationException();
        }

总结
迭代器的好处在容器里面更通用,提供了遍历和数据分离的模式,不互相影响。这个Iterator接口对象的作用是遍历,设计成内部类的好处,可以方便直接访问自己集合内部元素。使用起来只要list.iterator()使用接口的引用就可以。
好比飞机汽车火车上的空姐 只为当前的飞机里元素服务,别的飞机有别的空姐,反应出每个集合的迭代器只为当前的集合服务.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值