Java中Iterator迭代器原理探究

Java中爲了將各類對象放在一起,提供了容器這種東東,但衆所周知,Java裏容器不少,每一種容器的存儲結構都不同,當咱們須要遍歷容器裏的全部元素時便不可能只用一種或少有的幾種方法去方便地完成遍歷。那麼在Collection接口裏面定義了 iterator() 方法,而這個方法由各容器類去具體實現。Alei查看API文檔和某些容器類的源碼,發現此方法返回了一個Iterator接口對象,準確的說,是返回了一個能夠專門迭代各容器類的迭代器對象。以ArrayList爲例,iterator() 方法返回了一個屬於容器類裏面的私有內部類Itr的一個對象,並可能(當把返回值賦予一個迭代器引用)將這個對象的虛擬內存地址交給Iterator接口的一個引用:java

一、當調用ArrayList類的 iterator() 的方法時:ide

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

二、ArrayList裏面又定義Itr內部類,你將看到,hasNext()、next()、remove()是在這個內部類裏面重寫的。ui

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();
        }
    }

其餘各容器類對實現 iterator() 的方法並不相同,但最終都會返回一個屬於本身的迭代器,且已經將Iterator接口裏定義的方法重寫過。這下Alei基本理解了迭代器,且不是那麼懵逼了^_^!this

相關文章
相關標籤/搜索