java学习之迭代器浅谈

来源:互联网 发布:gis制作数据分布地图 编辑:程序博客网 时间:2024/06/06 17:32

1、 为什么用迭代器?在进行集合的遍历时,我们需要根据不同的集合来写不同的for循环.。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。这也减少重复代码的产生。

2、 怎么实现迭代器?首先Collection接口继承了Iterable接口。在Iterable接口中只是定义了一个方法iterator()返回一个在一组 T 类型的元素上进行迭代的迭代器。 实现了Collection接口的类较多,这里就不在一一列举,还有一部分继续继承Collection接口的子接口。实现类一般分为两类:实现了该接口的抽象类(AbstractList<E>,AbstractSet<E>,AbstractMap<E>)和类。对于实现了该接口的抽象类,利用内部类实现iterator()方法。对于子接口而言,依然没有实现父类接口的方法(他也不能实现)。对于ArrayList和LinkedList而言,其继承了抽象的List类,实现了List接口还有其他的接口。由于继承了抽象的List类,所以可以采用iterator()方法,返回一个迭代器对象。

3、 在抽象类中的具体实现:

    private class Itr implementsIterator<E> {

       

        int cursor = 0;//”游标”,是子查询返回的本次操作的开始地址

 

        /**

         * Index of element returned by mostrecent call to next or

         * previous.  Reset to -1 if this element is deleted by acall

         * to remove.

         */

        int lastRet = -1;//最近返回的下一个或者前一个的元素索引,如果这个元素被回调函数移除。

        /**

           *list的状态标记modCount赋值给迭代器的状态标记。这里要约束的是只有一个迭代器对象在对其操作。

          */

        int expectedModCount = modCount;

 

        public boolean hasNext() {

               //如果到list的最后一个元素,返回false。

            return cursor != size();

        }

//随着每次迭代,工作下标每次后移一位,最后一个元素取完,工作指针的大小和size()的返回值相等,所以hasNext()返回false,不再进行下一步的迭代。

        public E next() {

            checkForComodification();//每调用一次next()函数都会调用checkForComodification方法判断

            try {

                int i = cursor;//将工作下标付给I;

                E next = get(i);//取第i个元素

                lastRet = i;

                cursor = i + 1;

                return next;

            } catch (IndexOutOfBoundsExceptione) {

                checkForComodification();

                throw newNoSuchElementException();

            }

        }

 

        public void remove() {

            if (lastRet < 0)//无元素时无法移除元素。

                throw newIllegalStateException();

            checkForComodification();//检测是否满足删除条件

            try {

                AbstractList.this.remove(lastRet);

                if (lastRet < cursor)

                    cursor--;

                lastRet = -1;

                expectedModCount = modCount;

            } catch (IndexOutOfBoundsExceptione) {

                throw newConcurrentModificationException();

            }

        }

//此方法用来判断创建迭代对象的时候List的modCount与现在List的modCount是否一样,不一样的话就报ConcurrentModificationException异常

        final void checkForComodification() {

            if (modCount != expectedModCount)

                throw newConcurrentModificationException();

        }

}

 List对象有一个成员变量modCount,它代表该List对象被修改的次数,每对List对象修改一次,modCount都会加1。Itr类里有一个成员变量expectedModCount,它的值为创建Itr对象的时候List的modCount值。用此变量来检验在迭代过程中List对象是否被修改了,如果被修改了则抛出java.util.ConcurrentModificationException异常。在每次调用Itr对象的next()方法的时候都会调用checkForComodification()方法进行一次检验,checkForComodification()方法中做的工作就是比较expectedModCount modCount的值是否相等,如果不相等,就认为还有其他对象正在对当前的List进行操作,那个就会抛出ConcurrentModificationException异常。

0 0
原创粉丝点击