A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 大蓝鲸Java 于 2017-11-29 00:08 编辑

【南京校区】毁人不倦篇之二 --- 迭代器完全解析

在我们平时Java的学习过程中,有一些常识性问题,我们都默守陈规的遵守了这些的原则,殊不知我们的Java是一个极具自由的语言,正如我们程序员的一样,放荡不羁爱自由。                在我们平时写一些代码的时候,如果多思考一下,往往会有一些出乎意料的答案产生。

比如:毁人不倦篇之二 --- 迭代器完全解析

       首先API中,以及现在网络上各种对迭代器的解析并不全面,且解释有误。这是被API给坑了。
        API中关于迭代器中next方法解释如下:
         next();   返回迭代的下一个元素
         这里不禁有很多人会认为迭代器刚开始的时候指向的是集合中的-1索引处
         但是实际上真的是这样吗?
          我们翻看源码
          int cursor; 是做为一个成员变量了,int类型的成员变量初始化值为0.所以显然并不是如API中所说。
         关于迭代器的具体分析会在下文详细解释。
        首先,迭代器是设计模式中的一种。        迭代器设计模式:
                   提供一种方法访问容器中的各个元素,而又不暴露该对象的内部细节。
         使用场景:
                和容器经常在一起,我们定义了一个容器,还要提供外部访问的方法,迭代器模式无疑是最好不过了。
         
[AppleScript] 纯文本查看 复制代码
 private class Itr implements Iterator<E> {[/align]        int cursor;      //游标,可理解为指针。初始化默认值是0.
        int lastRet = -1; //一个控制不能连续remove的变量
        int expectedModCount = modCount;//并发修改异常的控制条件

        public boolean hasNext() { //判断是否有元素可迭代
            return cursor != size;  //实际就是判断当前游标指向的那个索引是否有元素
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();//并发修改异常的判断
            int i = cursor;//将游标赋值给一个局部变量i
            if (i >= size)//如果超出集合的最大索引
                throw new NoSuchElementException();//报没有元素异常
            Object[] elementData = ArrayList.this.elementData;//将集合拷贝一个副本
            if (i >= elementData.length)//此时i的值记录的是游标的值
                throw new ConcurrentModificationException();//如果游标大于副本的长度,则同样报并发修改异常                                                             //但是这个判断不会走到,因为副本的长度即集合的长度
                                                              //
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            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() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
















您需要登录后才可以回帖 登录 | 加入黑马