List體系以下:node
類與接口說明:編程
一、Collection:高度抽象出來的集合、定義某一類集合所具備的基本的方法、標準。數組
二、Iterable:標識性接口、要求子類提供獲取Iterator方法、而且要實現Iterator具備的幾個方法。安全
三、Iterator:迭代器、用於迭代Collection中元素、要求子類必須實現獲取Iterator的方法。數據結構
四、List:以隊列的形式存儲、操做元素、定義了這種形式的集合所具備的基本方法、以及方法的定義。要求List實現類集合中每一個元素都有索引、索引值從0開始。多線程
五、AbstractCollection:Collection的實現類、要求須要實現Collection接口的類都必須從它繼承、目的是用於簡化編程。併發
六、AbstractList:繼承AbstractCollection、實現List接口中定義方法、目的也是簡化編程、而且其內部提供了獲取Iterator、ListIterator的方法。工具
七、AbstractSequencedList:繼承AbstractList、使得List支持有序隊列、好比鏈表形式存儲操做元素。性能
八、ArrayList:繼承AbstractList、以動態數組的形式存儲、操做元素。this
九、LinkedList:繼承AbstractSequencedList、實現Deque、List接口、以雙向鏈表的形式存儲、操做元素。
十、Vector:繼承AbstractList、以動態數組的形式存儲、操做元素、線程安全。
ArrayList 與 LinkedList對比:
相同點:
1)都直接或者間接繼承了AbstractList,因此都支持以索引的方式操做元素;
2)都不須要擔憂容量問題,ArrayList是經過動態數組的形式來保存數據的,當容量不足會自動擴容。(注:ArrayList初始化容量爲10,擴容代碼以下:)
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
3)都是線程不安全的、通常用於單線程的環境下、要想在併發的環境下使用可使用Collections工具類包裝。
不一樣點:
1)ArrayList是經過動態數據保存數據的,LinkedList是經過雙向鏈表保存數據的;
2)相對與ArrayList而言,LinkedList繼承了AbstractSequentialList,而AbstractSequentialList繼承了AbstractList,因此使得LinkedList不只保留了以索引操做元素的功能,同時實現了雙向鏈表所具備的功能;
3)對集合中元素進行不一樣的操做效率不一樣、LinkedList善於刪除、添加元素、ArrayList善於查找元素。本質就是不一樣數據結構之間差別。
ArrayList 與 Vector的對比:
相同點:
1)都是繼承AbstractList、擁有相同的方法的定義;
2)內部都是以動態數組來存儲、操做元素的、而且均可以自動擴容。
不一樣點:
1)線程安全:ArrayList是線程不安全的、適用於單線程的環境下、Vector是線程安全的、使用與多線程的環境下;
2)構造方法:Vector有四個構造方法、比ArrayList多一個能夠指定每次擴容多少的構造方法;
3)擴容問題:每當動態數組元素達到上線時、ArrayList擴容爲1.5倍,Vector爲2倍;Vector擴容代碼以下:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
4)效率問題:由於Vector要同步方法、這個是要消耗資源的、因此效率會比較低下;
數組、ArrayList、LinkedList、Vector操做元素對比:
實現機制 | 查詢 | 寫 | 迭代操做 | |
數組 | 連續內存區域保存元素數據 | 1 | 不支持 | 不支持 |
ArrayList | 以數組保存數據 | 2 | 2 | 2 |
LinkedList | 以鏈表保存數據 | 4 | 1 | 1 |
Vector | 以數組保存數據 | 3 | 3 | 3 |
數組犧牲長度變化,直接在內存在開闢固定空間保存數據,因此查詢速率最快,可是由於size大小固定,因此不支持寫操做。
a)ArrayList查詢的速率比LinkedList的快,二者都是經過索引去查找元素,ArrayList是直接經過index定位到元素位置,而LinkedList是經過二分法肯定元素位置範圍,再逐個查找,直到找到該元素爲止。相比ArrayList 來講LinkedList更耗時,更耗費資源。二者查詢元素源碼以下:
/** *ArrayList經過索引查詢元素 **/ public E get(int index) { rangeCheck(index); return elementData(index); } E elementData(int index) { return (E) elementData[index]; } /** *LinkedList經過索引查詢元素 **/ public E get(int index) { checkElementIndex(index); return node(index).item; } Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
可是ArrayList的寫操做效率明顯低於LinkedList,緣由以下:
對於指定index處的插入、刪除、ArrayList和LinkedList都是先經過索引查找到指定位置、而後進行下一步的插入刪除操做、上面咱們知道LinkedList是先經過二分法查找index範圍再肯定index具體位置、可是ArrayList是直接定位到index處、爲何LinkedList反而快?依然經過源碼找緣由。
對比上面代碼能夠看出來ArrayList每當插入一個元素時、都會調用System.arraycopy()將指定位置後面的全部元素後移一位、從新構造一個數組、這是比較消耗資源的、而LinkedList是直接改變index先後元素的上一個節點和下一個節點的引用、而不須要動其餘的東西、因此效率很高。
ArrayList、Vector都是繼承與AbstractList、而且在類結構上沒有多少差別、可是由於Vector要同步方法、因此在性能上不如ArrayList、從源碼也能夠看出Vector許多方法都是使用關鍵字synchronized修飾的。