Java 集合 ArrayList VS LinkedList VS Vector

更多 Java 集合類方面的文章,請參見文集《Java 集合類》


共同點(diǎn):

  • 都實(shí)現(xiàn)了 List 接口
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

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

public class Vector<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 都可以插入 null

基本區(qū)別:

  • 實(shí)現(xiàn)方式:

    • ArrayList 和 Vector 基于數(shù)組實(shí)現(xiàn)浦箱,可以隨機(jī)訪問搔耕,實(shí)現(xiàn)了 RandomAccess 接口
    • LinkedList 基于鏈表實(shí)現(xiàn)挥等,不可隨機(jī)訪問粥惧,實(shí)現(xiàn)了 Deque 接口
  • 初始容量:

    • ArrayList 初始容量為 10
    • Vector 初始容量為 10
    • LinkedList 基于鏈表實(shí)現(xiàn)匕积,初始容量為 0
  • 擴(kuò)容方式:

    • ArrayList 數(shù)組容量不夠時橡卤,擴(kuò)容 50% int newCapacity = oldCapacity + (oldCapacity >> 1);
    • Vector 數(shù)組容量不夠時扮念,擴(kuò)容 100%
    • LinkedList 基于鏈表實(shí)現(xiàn),無需考慮擴(kuò)容
  • 是否線程安全:

    • ArrayList 線程不安全
    • Vector 線程安全
    • LinkedList 線程不安全

ArrayList 的實(shí)現(xiàn)原理

構(gòu)造

  • public ArrayList() 可以構(gòu)造一個默認(rèn)初始容量為 10 的空列表碧库;
    • private static final int DEFAULT_CAPACITY = 10;
  • public ArrayList(int initialCapacity) 構(gòu)造一個指定初始容量的空列表柜与;
  • public ArrayList(Collection<? extends E> c) 構(gòu)造一個包含指定 collection 的元素的列表巧勤,這些元素按照該 collection 的迭代器返回它們的順序排列的。

調(diào)整數(shù)組容量

每當(dāng)向數(shù)組中添加元素時弄匕,都要去檢查添加后元素的個數(shù)是否會超出當(dāng)前數(shù)組的長度颅悉,如果超出,數(shù)組將會進(jìn)行擴(kuò)容迁匠,以滿足添加數(shù)據(jù)的需求剩瓶。
數(shù)組擴(kuò)容有兩個方法:

  • 開發(fā)者可以通過一個 public 的方法 ensureCapacity(int minCapacity) 來增加 ArrayList 的容量:
public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY;

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
  • 而在存儲元素等操作過程中,如果遇到容量不足城丧,會調(diào)用 private 方法 private void ensureCapacityInternal(int minCapacity)
    實(shí)現(xiàn):
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
 * 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);
}

數(shù)組的擴(kuò)容操作的代價是很高的延曙,因此在實(shí)際使用時,我們應(yīng)該盡量避免數(shù)組容量的擴(kuò)張亡哄。

  • 當(dāng)我們可預(yù)知要保存的元素的多少時枝缔,要在構(gòu)造 ArrayList 實(shí)例時,就指定其容量蚊惯,以避免數(shù)組擴(kuò)容的發(fā)生愿卸。
  • 或者根據(jù)實(shí)際需求,通過調(diào)用 ensureCapacity 方法來手動增加 ArrayList 實(shí)例的容量截型。

LinkedList 的實(shí)現(xiàn)原理

使用鏈表

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

雙端鏈表

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;

引用:
ArrayList 的實(shí)現(xiàn)原理
LinkedList 的實(shí)現(xiàn)原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趴荸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宦焦,更是在濱河造成了極大的恐慌赊舶,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赶诊,死亡現(xiàn)場離奇詭異笼平,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)舔痪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門寓调,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锄码,你說我怎么就攤上這事夺英。” “怎么了滋捶?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵痛悯,是天一觀的道長。 經(jīng)常有香客問我重窟,道長载萌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮扭仁,結(jié)果婚禮上垮衷,老公的妹妹穿的比我還像新娘。我一直安慰自己乖坠,他們只是感情好搀突,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著熊泵,像睡著了一般仰迁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上顽分,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天徐许,我揣著相機(jī)與錄音,去河邊找鬼怯邪。 笑死绊寻,一個胖子當(dāng)著我的面吹牛花墩,可吹牛的內(nèi)容都是我干的悬秉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼冰蘑,長吁一口氣:“原來是場噩夢啊……” “哼和泌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起祠肥,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤武氓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后仇箱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體县恕,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年剂桥,在試婚紗的時候發(fā)現(xiàn)自己被綠了忠烛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡权逗,死狀恐怖美尸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斟薇,我是刑警寧澤师坎,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站堪滨,受9級特大地震影響胯陋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一惶岭、第九天 我趴在偏房一處隱蔽的房頂上張望寿弱。 院中可真熱鬧,春花似錦按灶、人聲如沸症革。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽噪矛。三九已至,卻和暖如春铺罢,著一層夾襖步出監(jiān)牢的瞬間艇挨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工韭赘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缩滨,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓泉瞻,卻偏偏與公主長得像脉漏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子袖牙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

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