JAVA學(xué)習(xí)-Iterator迭代器詳解

1.定義

Iterator的定義為:對Collection進(jìn)行迭代的迭代器,Iterator取代了Java Collection Framework中的 Enumeration。Iterator與Enumeration主要有兩點不一樣:

1.迭代器允許在調(diào)用者從集合中刪除元素

2.迭代器的方法名有所改進(jìn)

以上是Java Api對Iterator的介紹,該接口主要定義了如下代碼的規(guī)則

public interface Iterator<E> {
    //是否有下一個元素
    boolean hasNext();
    //獲取當(dāng)前元素
    E next();
    //刪除元素
    void remove();
}

在使用Iterator時,我遇到如下兩個問題,

1.Iterator是什么,這便是上述介紹的內(nèi)容

2.為何使用Iterator,換句話說Iterator能做什么,下面將通過ArrayList中的Iterator的實現(xiàn)介紹Iterator的原理及應(yīng)用

2.原理及實現(xiàn)

在ArrayList中有兩個內(nèi)部類,都實現(xiàn)了Iterator接口,分別為Itr與ListItr,如下首先介紹Itr的源碼

private class Itr implements Iterator<E> {
    //游標(biāo)記錄當(dāng)前索引的位置,是從0開始的
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;//記錄元素修改記錄,若在迭代List時,modCount發(fā)生變化將會拋出ConcurrentModificationException異常

    //判斷游標(biāo)是否到達(dá)最后的位置,若沒有表示還有元素,若有則沒有元素了
    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        //校驗是否被修改(其實這里存在多線程問題,所以說ArrayList不是線程安全的)
        checkForComodification();
        int i = cursor;//當(dāng)前游標(biāo)的位置
        if (i >= size)//若游標(biāo)的位置比數(shù)組長度還大則
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;//游標(biāo)向后移動1
        return (E) elementData[lastRet = i];//返回值并且賦值
    }

    public void remove() {
        //lastRet初始值為-1,若需要調(diào)用remove方法,則bi
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            //刪除lastRet索引處的元素
            ArrayList.this.remove(lastRet);
            
            //游標(biāo)前移,由于是刪除remove方法刪除的是lastRet位置的元素則游標(biāo)需要前移才能保證可以遍歷到所有的元素
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    //檢查列表是否修改,若修改則拋出異常
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

通過源碼可以發(fā)現(xiàn)迭代器的方式遍歷列表是不需要知道list的長度的,只需要判斷是否具有元素就可以進(jìn)行遍歷了,如下代碼所示

//1.獲取迭代器
Iterator<String> ite = arrayList.iterator();
//2.判斷是否遍歷結(jié)束
while (ite.hasNext()){
     System.out.println(ite.next());
}

在ArryList詳解中我有提到使用Iterator可以實現(xiàn)在對List進(jìn)行遍歷是進(jìn)行刪除操作,具體代碼如下所示

Iterator<String> ite = arrayList.listIterator();
while (ite.hasNext()){
    if(ite.next() == "a")
        ite.remove();
}
System.out.println(arrayList);

這里需要思考一個問題,ite.remove()方法調(diào)用的實際上是ArrayList的remove(index)方法,也改變了數(shù)組的長度大小并且數(shù)組元素也發(fā)生了變化,那為什么使用這種方式可以得到正常的結(jié)果?

其實這需要從迭代器的remove的源碼進(jìn)行分析, 下面舉例分析,list中的初始值為[a,b,c,d],當(dāng)lastRet=0時,此時cursor=1,首先執(zhí)行A處的代碼,此時list變成[b,c,d],若要重新遍歷那就要把cursor變成上次刪除出的元素的索引,即執(zhí)行B處的代碼,這里便是迭代器循環(huán)刪除元素時可以得到正常的結(jié)果原因,利用游標(biāo)的方式在刪除元素后移動游標(biāo)達(dá)到可以遍歷到所有元素的目的

    ArrayList.this.remove(lastRet);//A
    cursor = lastRet;//B
    lastRet = -1;//C
    expectedModCount = modCount;//D

3.總結(jié)

本文主要針對Iterator一個基本的實現(xiàn)做了相關(guān)的介紹,后續(xù)還會根據(jù)深入的去理解其中的原理,如有問題希望指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 場景問題# 1.1 工資表數(shù)據(jù)的整合## 考慮這樣一個實際應(yīng)用:整合工資表數(shù)據(jù)。 這個項目的背景是這樣的,項目...
    七寸知架構(gòu)閱讀 2,640評論 0 53
  • 一.集合框架 1.集合框架(對象數(shù)組的概述和使用) a.案例演示 * 需求:我有5個學(xué)生,請把這個5個學(xué)生的信息存...
    夢游的沙師弟閱讀 624評論 0 1
  • Java源碼研究之容器(1) 如何看源碼 很多時候我們看源碼, 看完了以后經(jīng)常也沒啥收獲, 有些地方看得懂, 有些...
    駱駝騎士閱讀 1,056評論 0 22
  • 順著石階,我從蒼翠欲滴的濃蔭里走下百牙山,來到百荷北園。高聳的古塔佇立在身后,來時路依舊那般沉寂,那般寧靜。山色塔...
    xiaoxiaoningxia閱讀 520評論 1 2
  • 某談話節(jié)目現(xiàn)場,在場眾人就“父母與孩子之間的隔閡”這一話題爭論不休。 一位嘉賓席上的情感專家說:“這個問題的根源就...
    云墨客閱讀 240評論 0 0

友情鏈接更多精彩內(nèi)容