List詳解(ArrayList套硼、LinkedList、Vector)

List詳解

List 我們需要保留存儲順序胞皱,并且保留重復元素邪意,使用List
ArrayList 查詢較多的時候使用ArrayList
LinkedList 存取較多的時候使用LinkedList
Vector 需要保證線程安全的時候使用Vector
  • Arraylist: Object數(shù)組

  • LinkedList: 雙向鏈表(JDK1.6之前為循環(huán)鏈表,JDK1.7取消了循環(huán))

  • Vector: Object數(shù)組

ArrayList

ArrayList 是一個數(shù)組隊列反砌,相當于 動態(tài)數(shù)組雾鬼。與Java中的數(shù)組相比,它的容量能動態(tài)增長宴树。

它繼承于AbstractList策菜,實現(xiàn)了List, RandomAccess, Cloneable, java.io.Serializable這些接口。

和Vector不同森渐,ArrayList中的操作不是線程安全的做入!所以,建議在單線程中才使用ArrayList同衣,而在多線程中可以選擇Vector或者CopyOnWriteArrayList竟块。

繼承關系

? java.util.AbstractCollection<E>  
  ? java.util.AbstractList<E>  
    ? java.util.ArrayList<E>

public class ArrayList<E> extends AbstractList<E>  implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

構造函數(shù)

// 默認構造函數(shù)  
ArrayList()
// capacity是ArrayList的默認容量大小。當由于增加數(shù)據(jù)導致容量不足時耐齐,容量會添加上一次容量大小的一半浪秘。  
ArrayList(int capacity)
// 創(chuàng)建一個包含collection的ArrayList  ArrayList(Collection<? extends E> collection)

底層原理實現(xiàn)

ArrayList包含了兩個重要的對象:elementDatasize

transient Object[] elementData;
  • elementData 是"Object[]類型的數(shù)組"埠况,它保存了添加到ArrayList中的元素耸携。實際上,elementData是個動態(tài)數(shù)組辕翰,我們能通過構造函數(shù) ArrayList(int initialCapacity)來執(zhí)行它的初始容量為initialCapacity夺衍;如果通過不含參數(shù)的構造函數(shù)ArrayList()來創(chuàng)建ArrayList,則elementData的容量默認是10喜命。elementData數(shù)組的大小會根據(jù)ArrayList容量的增長而動態(tài)的增長沟沙。
private int size;
  • size 則是動態(tài)數(shù)組的實際大小河劝。

遍歷方式

  • 第一種,通過迭代器遍歷矛紫。
    Integer value = null;  Iterator iter = list.iterator();  while (iter.hasNext()) {  value = (Integer)iter.next();  }
  • 第二種赎瞎,隨機訪問,通過索引值去遍歷颊咬。
    Integer value = null;  int size = list.size();  for (int i=0; i<size; i++) {  value = (Integer)list.get(i); }
  • 第三種务甥,for循環(huán)遍歷
Integer value = null;  for (Integer integ:list) {  value = integ;  }

遍歷ArrayList時喳篇,使用隨機訪問(即敞临,通過索引序號訪問)效率最高,而使用迭代器的效率最低杭隙!

API

// Collection中定義的API
boolean             add(E object)
boolean             addAll(Collection<? extends E> collection)
void                clear()
boolean             contains(Object object)
boolean             containsAll(Collection<?> collection)
boolean             equals(Object object)
int                 hashCode()
boolean             isEmpty()
Iterator<E>         iterator()
boolean             remove(Object object)
boolean             removeAll(Collection<?> collection)
boolean             retainAll(Collection<?> collection)
int                 size()
<T> T[]             toArray(T[] array)
Object[]            toArray()
// AbstractCollection中定義的API
void                add(int location, E object)
boolean             addAll(int location, Collection<? extends E> collection)
E                   get(int location)
int                 indexOf(Object object)
int                 lastIndexOf(Object object)
ListIterator<E>     listIterator(int location)
ListIterator<E>     listIterator()
E                   remove(int location)
E                   set(int location, E object)
List<E>             subList(int start, int end)
// ArrayList新增的API
Object               clone()
void                 ensureCapacity(int minimumCapacity)
void                 trimToSize()
void                 removeRange(int fromIndex, int toIndex)

LinkedList

LinkedList 是一個繼承于AbstractSequentialList的雙向鏈表哟绊。它也可以被當作堆棧、隊列或雙端隊列進行操作痰憎。

LinkedList 是非同步的票髓。

繼承關系

java.lang.Object  
  ? java.util.AbstractCollection<E>  
    ? java.util.AbstractList<E> 
     ? java.util.AbstractSequentialList<E> 
       ? java.util.LinkedList<E>

public class LinkedList<E>  extends AbstractSequentialList<E>  
implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}

構造函數(shù)

// 默認構造函數(shù)  
LinkedList()
// 創(chuàng)建一個LinkedList,保護Collection中的全部元素铣耘。  LinkedList(Collection<? extends E> collection)

底層原理

LinkedList的本質(zhì)是雙向鏈表洽沟。 (01) LinkedList繼承于AbstractSequentialList,并且實現(xiàn)了Dequeue接口蜗细。 (02) LinkedList包含兩個重要的成員:header 和 size裆操。 header是雙向鏈表的表頭,它是雙向鏈表節(jié)點所對應的類Entry的實例炉媒。Entry中包含成員變量: previous, next, element踪区。其中,previous是該節(jié)點的上一個節(jié)點吊骤,next是該節(jié)點的下一個節(jié)點缎岗,element是該節(jié)點所包含的值。   size是雙向鏈表中節(jié)點的個數(shù)白粉。

遍歷方式

  • 第一種传泊,通過迭代器遍歷。
for(Iterator iter = list.iterator(); iter.hasNext();)  iter.next();
  • 通過快速隨機訪問遍歷LinkedList
int size = list.size();  for (int i=0; i<size; i++) {  list.get(i); }
  • 通過另外一種for循環(huán)來遍歷LinkedList
for (Integer integ:list) ;
  • 通過pollFirst()來遍歷LinkedList
while(list.pollFirst() != null)  ;
  • 通過pollLast()來遍歷LinkedList
while(list.pollLast() != null)  ;
  • 通過removeFirst()來遍歷LinkedList
try {  while(list.removeFirst() != null)  ;  } catch (NoSuchElementException e) {  }
  • 通過removeLast()來遍歷LinkedList
try {  while(list.removeLast() != null)  ;  } catch (NoSuchElementException e) {  }

遍歷LinkedList時鸭巴,使用removeFist()或removeLast()效率最高眷细。但用它們遍歷時,會刪除原始數(shù)據(jù)鹃祖;若單純只讀取溪椎,而不刪除,應該使用第3種遍歷方式。 無論如何池磁,千萬不要通過隨機訪問去遍歷LinkedList奔害!

API

boolean       add(E object)
void          add(int location, E object)
boolean       addAll(Collection<? extends E> collection)
boolean       addAll(int location, Collection<? extends E> collection)
void          addFirst(E object)
void          addLast(E object)
void          clear()
Object        clone()
boolean       contains(Object object)
Iterator<E>   descendingIterator()
E             element()
E             get(int location)
E             getFirst()
E             getLast()
int           indexOf(Object object)
int           lastIndexOf(Object object)
ListIterator<E>     listIterator(int location)
boolean       offer(E o)
boolean       offerFirst(E e)
boolean       offerLast(E e)
E             peek()
E             peekFirst()
E             peekLast()
E             poll()
E             pollFirst()
E             pollLast()
E             pop()
void          push(E e)
E             remove()
E             remove(int location)
boolean       remove(Object object)
E             removeFirst()
boolean       removeFirstOccurrence(Object o)
E             removeLast()
boolean       removeLastOccurrence(Object o)
E             set(int location, E object)
int           size()
<T> T[]       toArray(T[] contents)
Object[]     toArray()

Vector

Vector 是矢量隊列楷兽,它是JDK1.0版本添加的類地熄。繼承于AbstractList,實現(xiàn)了List, RandomAccess, Cloneable這些接口芯杀。

繼承關系

java.lang.Object  
  ? java.util.AbstractCollection<E>  
    ? java.util.AbstractList<E>  
      ? java.util.Vector<E>

public class Vector<E>  extends AbstractList<E>  implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

構造函數(shù)

Vector共有4個構造函數(shù)  
// 默認構造函數(shù)  
Vector()
// capacity是Vector的默認容量大小端考。當由于增加數(shù)據(jù)導致容量增加時,每次容量會增加一倍揭厚。  
Vector(int capacity)
// capacity是Vector的默認容量大小却特,capacityIncrement是每次Vector容量增加時的增量值。  
Vector(int capacity, int capacityIncrement)
// 創(chuàng)建一個包含collection的Vector  
Vector(Collection<? extends E> collection)

底層原理

Vector的數(shù)據(jù)結構和ArrayList差不多筛圆,它包含了3個成員變量:elementData , elementCount裂明, capacityIncrement。

(01) elementData 是"Object[]類型的數(shù)組"太援,它保存了添加到Vector中的元素闽晦。elementData是個動態(tài)數(shù)組,如果初始化Vector時提岔,沒指定動態(tài)數(shù)組的>大小仙蛉,則使用默認大小10。隨著Vector中元素的增加碱蒙,Vector的容量也會動態(tài)增長荠瘪,capacityIncrement是與容量增長相關的增長系數(shù),具體的增長方式赛惩,請參考源碼分析中的ensureCapacity()函數(shù)哀墓。

(02) elementCount 是動態(tài)數(shù)組的實際大小。

(03) capacityIncrement 是動態(tài)數(shù)組的增長系數(shù)喷兼。如果在創(chuàng)建Vector時篮绰,指定了capacityIncrement的大小褒搔;則阶牍,每次當Vector中動態(tài)數(shù)組容量增加時>,增加的大小都是capacityIncrement星瘾。

遍歷方式

  • 第一種走孽,通過迭代器遍歷。
Integer value = null;  int size = vec.size();  for (int i=0; i<size; i++) {  value = (Integer)vec.get(i); }
  • 第二種琳状,隨機訪問磕瓷,通過索引值去遍歷。
Integer value = null;  int size = vec.size();  for (int i=0; i<size; i++) {  value = (Integer)vec.get(i); }
  • 第三種,另一種for循環(huán)困食。
Integer value = null;  for (Integer integ:vec) {  value = integ;  }
  • 第四種边翁,Enumeration遍歷
Integer value = null;  Enumeration enu = vec.elements();  while (enu.hasMoreElements()) {  value = (Integer)enu.nextElement();  }

總結:遍歷Vector硕盹,使用索引的隨機訪問方式最快符匾,使用迭代器最慢。

API

synchronized boolean        add(E object)
             void           add(int location, E object)
synchronized boolean        addAll(Collection<? extends E> collection)
synchronized boolean        addAll(int location, Collection<? extends E> collection)
synchronized void           addElement(E object)
synchronized int            capacity()
             void           clear()
synchronized Object         clone()
             boolean        contains(Object object)
synchronized boolean        containsAll(Collection<?> collection)
synchronized void           copyInto(Object[] elements)
synchronized E              elementAt(int location)
             Enumeration<E> elements()
synchronized void           ensureCapacity(int minimumCapacity)
synchronized boolean        equals(Object object)
synchronized E              firstElement()
             E              get(int location)
synchronized int            hashCode()
synchronized int            indexOf(Object object, int location)
             int            indexOf(Object object)
synchronized void           insertElementAt(E object, int location)
synchronized boolean        isEmpty()
synchronized E              lastElement()
synchronized int            lastIndexOf(Object object, int location)
synchronized int            lastIndexOf(Object object)
synchronized E              remove(int location)
             boolean        remove(Object object)
synchronized boolean        removeAll(Collection<?> collection)
synchronized void           removeAllElements()
synchronized boolean        removeElement(Object object)
synchronized void           removeElementAt(int location)
synchronized boolean        retainAll(Collection<?> collection)
synchronized E              set(int location, E object)
synchronized void           setElementAt(E object, int location)
synchronized void           setSize(int length)
synchronized int            size()
synchronized List<E>        subList(int start, int end)
synchronized <T> T[]        toArray(T[] contents)
synchronized Object[]       toArray()
synchronized String         toString()
synchronized void           trimToSize()

參考文獻:

Java 集合系列目錄(Category)

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘩例,一起剝皮案震驚了整個濱河市啊胶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垛贤,老刑警劉巖焰坪,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異聘惦,居然都是意外死亡某饰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門善绎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來黔漂,“玉大人,你說我怎么就攤上這事涂邀∥练拢” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵比勉,是天一觀的道長劳较。 經(jīng)常有香客問我,道長浩聋,這世上最難降的妖魔是什么观蜗? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮衣洁,結果婚禮上墓捻,老公的妹妹穿的比我還像新娘。我一直安慰自己坊夫,他們只是感情好砖第,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著环凿,像睡著了一般梧兼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上智听,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天羽杰,我揣著相機與錄音渡紫,去河邊找鬼。 笑死考赛,一個胖子當著我的面吹牛惕澎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颜骤,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼唧喉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了复哆?” 一聲冷哼從身側響起欣喧,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梯找,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體益涧,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡锈锤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了闲询。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片久免。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖扭弧,靈堂內(nèi)的尸體忽然破棺而出阎姥,到底是詐尸還是另有隱情,我是刑警寧澤鸽捻,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布呼巴,位于F島的核電站,受9級特大地震影響御蒲,放射性物質(zhì)發(fā)生泄漏衣赶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一厚满、第九天 我趴在偏房一處隱蔽的房頂上張望府瞄。 院中可真熱鬧,春花似錦碘箍、人聲如沸遵馆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽货邓。三九已至,卻和暖如春多艇,著一層夾襖步出監(jiān)牢的瞬間逻恐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留复隆,地道東北人拨匆。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像挽拂,于是被迫代替她去往敵國和親惭每。 傳聞我的和親對象是個殘疾皇子亏栈,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容