实现文本编辑器的设计与实现_ArrayList实现分析(三)——迭代器的实现
ArrayList的迭代器的使用,在ArrayList中,通過調(diào)用iterator()就可以完成迭代器的創(chuàng)建。代碼如下:
public Iterator iterator() { return new Itr(); }由上面的源碼可知,在iterator方法內(nèi)部創(chuàng)建了創(chuàng)建了一個Itr類型,該類是定義在ArrayList中的一個私有內(nèi)部類,它實現(xiàn)了Iterator接口。
在jdk1.8中,接口Iterator一共有四個方法:
//是否還有下一個元素boolean hasNext();//下一個元素E next();//刪除當前的元素void remove(); //對list中的每個元素進行action操作void forEachRemaining(Consumer super E> action);內(nèi)部類Itr它有三個屬性,對Iterator接口的方法實現(xiàn)是依賴下面三個屬性。
//當前元素的索引位置int cursor; //上一個元素的索引位置,主要用在Iterator的remove操作中。int lastRet = -1; //記錄當前l(fā)ist修改的次數(shù),使用當前l(fā)ist中的modCount來初始化int expectedModCount = modCount;下面先介紹Iterator的每個方法的實現(xiàn):
public boolean hasNext() { return cursor != size;}hasNext方法比較簡單,判斷下一個元素的索引是否與list大小相等,如果相等,表示當前元素已經(jīng)是list中的最后一個元素。下面介紹next方法,該方法是獲取當前元素:
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];}首先通過 checkForComodification()檢查在執(zhí)行Iterator遍歷的時候,如果有其他線程對該list進行了修改,那么會拋出異常。在內(nèi)部使用i變量來代替cursor,接著判斷i的值的合法性,然后給cursor完成加一操作,并且把當前i的值賦給lastRet并返回elementData[i]
下面介紹remove方法,
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(); }}由源碼可知,指向刪除操作其實是刪除lastRet所執(zhí)行的元素,而lastRet初始值是-1,因此當通過Iterator進行remove操作的時候,必須現(xiàn)在執(zhí)行next()操作,獲取到list中的第一個元素之后,才能執(zhí)行remove方法。由上面源碼可知當執(zhí)行完成 ArrayList.this.remove(lastRet)操作后,lastRet又重新被賦值為-1,因此不同通過Iterator對list連續(xù)做兩次remove操作。
下面介紹最后一個方法,也是1.8新增加的一個方法,該方法主要是對通過Iterator遍歷后,對list剩余元素進行consumer操作。
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; //這里第二次判斷合法性主要是預防其他線程對該list有增刪的操作 //當其他線程對list進行了曾刪操作,那么該方法會拋出異常,退出當前方法 if (i >= elementData.length) { throw new ConcurrentModificationException(); } //每次對List中剩余的元素進行consumer操作時,都需要來判斷一下list //有沒有被其他線程進行過增刪改的操作 while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } cursor = i; lastRet = i - 1; checkForComodification(); }首先是對cursor值的合法性進行判斷,然后是再次獲取elementData的大小,再判斷一次是否List被其他線程進行過元素的增加和刪除操作。校驗完成之后,就是開始對List中的每個元素執(zhí)行consumer操作,每次操作后通過判斷modCount == expectedModCount來檢查是否有其他線程對該list進行過修改操作。如果有,那么就會退出當前循環(huán),并且把cursor的指向List已經(jīng)執(zhí)行consumer操作的最后一個元素的索引,最后通過調(diào)用checkForComodification()拋出異常;否則,順利執(zhí)行完循環(huán),并且最后還是要執(zhí)行一次checkForComodification(),檢查是否在執(zhí)行forEachRemaining的時候,有其他線程對list進行增刪改操作。checkForComodification方法比較簡單,這里不做太多說明,具體見下面:
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();}總結(jié)
以上是生活随笔為你收集整理的实现文本编辑器的设计与实现_ArrayList实现分析(三)——迭代器的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内网通 去广告_新高一攻略|让我们一起跟
- 下一篇: python编写安装脚本_LAMP一键安