天天看點

有關ListIterator接口的add與remove方法探究

ListIterator接口繼承自Iterator接口,新增了add()等方法。

關于ListIterator的add()方法的作用(接口是沒有方法實作的,但其實作類對于add()方法的實作機制大緻相同,姑且這樣說吧),《java核心技術 卷I》裡如下表述:

    “如果多次調用add方法,将按照提供的次序把元素添加到連結清單中。它們被依次添加到疊代器目前位置之前。”

對于這種說法,很容易引發歧義,目前位置是什麼?目前指向的元素,還是遊标位置?

帶着這種疑問,我查閱了ListIterator接口的API說明文檔(網址見本文結尾),得到對于add()方法的如下英文描述:

Inserts the specified element into the list (optional operation). The element is inserted immediately before the element that would be returned by

next()

, if any, and after the element that would be returned by

previous()

, if any. (If the list contains no elements, the new element becomes the sole element on the list.)

該描述就很清晰:的确是把新元素插入由next()所傳回的那個元素之前,previous()所傳回的元素之後。之是以加之前與之後兩個限定,是為了應對在鍊尾(next傳回為空)以及鍊頭(previous傳回為空)的特殊情況,如果連結清單為空,則新插入的元素就作為該連結清單的唯一進制素。另外,每當插入一個元素以後,疊代器都會後移(向着鍊尾方向)一位。

舉例說明:

List<String> name=new LinkedList<String>();
name.add("A");
name.add("B");
name.add("C");
ListIterator<String> iter = name.listIterator();
iter.next();
iter.add("D");
iter.add("E");
for(String nm:name)
    System.out.println(nm);
           

第4行代碼執行完畢,name連結清單内容如下1A2B3C4(數字隻作為占位符,可以忽略,内容為ABC,從鍊頭到鍊尾)

第5行定義疊代器以後,初始疊代器的位置是在數字1,執行第6行next以後,疊代器指向數字2的位置,此時如果再執行next(),傳回B,執行previous(),傳回A,是以應把D插入AB之間,疊代器順移到DB之間;依次類推,可以插入E。最終輸出結果為:

A
D
E
B
C
           

下面再簡單看一下remove方法,關于remove方法,API文檔描述如下:

Removes from the list the last element that was returned by

next()

or

previous()

(optional operation). This call can only be made once per call to

next

or

previous

. It can be made only if

add(java.lang.Object)

has not been called after the last call to

next

or

previous

.

簡單解釋一下,要執行remove,首先要找到所需移除的元素,怎樣找?當然是通過next()跟previous()方法,是以remove必須要跟在next()或是previous()之後,而且隻能執行一次(一個元素當然隻能删一次,删多個元素,需要再執行next()或previous())。另外,在執行next()或previous()後還不能先執行了 add()方法。因為,否則add()方法執行以後,疊代器已經移動了,這樣所要删除的目标元素指向不明,會報”Unknown Source“異常。

是以《java核心技術 卷I》對add和remove方法總結如下:add方法隻依賴疊代器的位置(next和previous各傳回什麼元素),而remove方法依賴于疊代器的狀态(是否執行了next或remove方法)。(紅色是我的備注)

對于java API文檔,推薦GrepCode,網址如下:

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/ListIterator.java?av=h#ListIterator

這裡你能看到類或接口的繼承以及實作結構,同時還能檢視實作源碼,很不錯。

繼續閱讀