Java Iterator遍历List集合

什么是迭代器

迭代器是一个对象,它的工作是遍历并且选择序列中的对象(比如一个ArrayList),而客户端程序员不必知道或关心该序列底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价很小,经常可以看到对迭代器有一些奇怪的限制,例如,Java中的iterator只能单向移动,这个Iterator只能用来:

  • 使用iterator()方法要求容器返回一个Iterator对象。Iterator将准备好返回序列的第一个元素。
  • 使用next()或者序列中的写一个元素。 -使用hasNext()方法检查序列中是否还有元素。
  • 使用remove()方法将讲迭代器新返回的元素删除。

实例分析

package com.hand.hsp;

import java.util.*;

/**
 * Created by Moxie on 2016/12/25.
 */
public class TestIterator {

    public static void main(String[] args){
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0 ; i < 10 ; i++){
            list.add(i);
        }
        //调用ArrayList的iterator()方法返回一个 Iterator 对象
        Iterator<Integer> iterator = list.iterator();
        //从第一个元素开始遍历,每次获取一个新的元素
        while(iterator.hasNext()){
            int number = iterator.next();
            System.out.print(number + "        ");
        }
        System.out.println();

        int k = 0;
        iterator = list.iterator();
        while(k++ < 5 && iterator.hasNext()){
            /**
             * 注意下面这两条语句的顺序,第一次执行iterator.next()的时候取到的是第一个元素,然后再remove。
             * 如果顺序相反,则会抛出异常Exception in thread "main" java.lang.IllegalStateException,
             * 意思就是:在不合理或不正确时间内唤醒一方法时出现的异常信息。换句话说,
             * 即 Java 环境或 Java 应用不满足请求操作。
             */
            iterator.next();
            iterator.remove();
        }

        while(iterator.hasNext()){
            int number = iterator.next();
            System.out.print(number + "        ");
        }

    }


}

原理分析

Iterator的用途我们已经看到了,那么,它究竟是怎么实现的呢?这时候我们找到Iterator接口,发现它只声名了下面这几个方法

然后我们再找到ArrayList的iterator()方法,看看它是怎么实现的,从 833行开始,到903行(JDK1.8)

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

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

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

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            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() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

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

        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

看了源代码,是不是觉得有点熟悉?它是通过一个名叫 Itr 的内部类实现的,逻辑代码都写在内部类里面。这不是那种什么设计模式吗?迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。我们平时调用的iterator()方法,就是这样实现的,看了源码是不是觉得清爽了好多?

转载于:https://my.oschina.net/spilledyear/blog/1531867

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值