關於java集合框架中AbstractSequentialList類的理解

LinkedList是AbstractSequentialList的子類,而ArrayList是AbstractList的子類,AbstractSequentialList也是AbstractList的子類。編程

AbstractSequentialList的API文檔

這個類提供了一個基本的List接口實現,爲實現序列訪問的數據儲存結構的提供了所須要的最小化的接口實現。對於支持隨機訪問數據的List好比數組,應該優先使用AbstractListapi

這裏是與隨機訪問類AbstractList類中相對的另外一套系統,採用的是在迭代器的基礎上實現的get、set、add和remove方法數組

爲了實現這個列表。僅僅須要拓展這個類,而且提供ListIterator和size方法。 
對於不可修改的List,編程人員只須要實現Iterator的hasNext、next和hasPrevious、previous和index方法 
對於可修改的List還須要額外實現Iterator的的set的方法 
對於大小可變的List,還須要額外的實現Iterator的remove和add方法dom


AbstractSequentiaList和RandomAccess主要的區別是AbstractSequentiaList的主要方法都是經過迭代器實現的。而不是直接實現的(不經過迭代器,好比ArrayList實現的方式是經過數組實現的。)所以對於一些能夠提供RandomAccess的方法,直接使用方法可能更快。由於迭代器移動須要必定代價。源碼分析

源碼分析

AbstractSequentialList方法的實現並無特別須要注意的地方。主要是由於因爲大部分的方法均是經過listIterator(int)的方法實現。可是listIterator(int)方法是一個抽象方法,基本實現只能從LinkedList中分析。 
這裏簡單的分析一些編程技巧。spa

 1 public E set(int index, E element) {
 2         try {
 3             ListIterator<E> e = listIterator(index);
 4             E oldVal = e.next();
 5             e.set(element);
 6             return oldVal;
 7         } catch (NoSuchElementException exc) {
 8             throw new IndexOutOfBoundsException("Index: "+index);
 9         }
10     }
11     public E remove(int index) {
12         try {
13             ListIterator<E> e = listIterator(index);
14             E outCast = e.next();
15             e.remove();
16             return outCast;
17         } catch (NoSuchElementException exc) {
18             throw new IndexOutOfBoundsException("Index: "+index);
19         }
20     }

set和remove方法返回了以前的oldVal,這樣能夠用於一些其餘的操做。code

 1 public boolean addAll(int index, Collection<? extends E> c) {
 2         try {
 3             boolean modified = false;
 4             ListIterator<E> e1 = listIterator(index);
 5             Iterator<? extends E> e2 = c.iterator();
 6             while (e2.hasNext()) {
 7                 e1.add(e2.next());
 8                 modified = true;
 9             }
10             return modified;
11         } catch (NoSuchElementException exc) {
12             throw new IndexOutOfBoundsException("Index: "+index);
13         }
14     }

首先代碼很清晰。只須要說明三點: 
一個問題是迭代器e2並非要求是ListIterator,而僅僅是Iterator。換句話說並不對容器類型作要求。這也是利用了迭代器的優勢之一。 
第二個問題是這裏設定了一個modified的變量。用來表示原表是否被更改。這樣即便更改失敗了,也能夠經過返回值來判斷是否對原進行了修改。blog

1 ListIterator<E> e1 = listIterator(index);
2 Iterator<? extends E> e2 = c.iterator();

第三個問題是通用的問題,首先是這裏全部的方法都採用了這樣的結構接口

1 try {
2 } catch (NoSuchElementException exc) {
3       throw new IndexOutOfBoundsException("Index: "+index);
4 }

這裏將一個RuntimeException的未檢查錯誤轉換成了一個檢查錯誤IndexOutOfBoundsException而後拋出。根據我目前查到的解釋。大部分是說這樣作是爲了幫助將編程人員更好的定位問題。element

相關文章
相關標籤/搜索