首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

深入解析 Java 容器類:List、ArrayList 與 Vector 的核心差異與原理

     編輯:Java 相關知識

List 介面與實現類概覽

在 Java 集合框架中,List 介面定義了有序集合的標準行為,允許重複元素並支援索引存取。其兩大經典實現類 ArrayList 與 Vector 雖然底層皆以動態陣列(Object[] elementData)儲存資料,但在執行緒安全性與效能上有顯著差異。

ArrayList 核心結構與特性

ArrayList 內部維護兩個關鍵欄位:

  • Object[] elementData:實際儲存元素的陣列
  • int size:目前集合中元素的實際數量

預設建構子初始容量為 10,若指定初始容量則直接配置對應大小陣列。新增元素時會呼叫 ensureCapacity 確保空間足夠,擴容策略為 newCapacity = (oldCapacity * 3) / 2 + 1。值得注意的是,ArrayList 非執行緒安全,多執行緒環境下需外部同步或使用 Collections.synchronizedList 包裝。

Vector 的同步機制與效能考量

Vector 的方法均以 synchronized 修飾,保證執行緒安全。但這也意味著單執行緒場景下,ArrayList 效能更優。若元素數量固定,直接使用陣列效率最高。

實戰程式碼範例

public class ListDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        String[] strArr = new String[3];
        boolean ret = list.add("haha");
        list.add(new String("aa"));
        list.add(null);
        System.out.println(list.size()); // 3
        System.out.println(ret); // true
        System.out.println(list); // [haha, aa, null]
        System.out.println(strArr); // [LJava.lang.String;@1fee6fc
        System.out.println(strArr.getClass().getName()); // [LJava.lang.String;
        System.out.println(list.indexOf("aa")); // 1
        System.out.println(list.indexOf(null)); // 2
        String str = list.set(1, "ee");
        System.out.println(str); // aa
        System.out.println(list); // [haha, ee, null]
        String remove = list.remove(0);
        System.out.println(remove); // haha
        System.out.println(list); // [ee, null]
        boolean result = list.remove("ff");
        System.out.println(result); // false
        result = list.remove("ee");
        System.out.println(result); // true
        System.out.println(list); // [null]
    }
}

核心原始碼解析

建構子與擴容機制

public ArrayList() {
    this(10);
}
public ArrayList(int initialCapacity) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
    this.elementData = new Object[initialCapacity];
}
public boolean add(E e) {
    ensureCapacity(size + 1);
    elementData[size++] = e;
    return true;
}
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3) / 2 + 1;
        if (newCapacity < minCapacity)
            newCapacity = minCapacity;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

刪除操作與陣列位移

public E remove(int index) {
    rangeCheck(index);
    modCount++;
    E oldValue = (E) elementData[index];
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index + 1, elementData, index, numMoved);
    elementData[--size] = null; // 釋放最後位置引用,利於 GC 回收
    return oldValue;
}

查找、替換與存取

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i] == null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

public E set(int index, E element) {
    rangeCheck(index);
    E oldValue = (E) elementData[index];
    elementData[index] = element;
    return oldValue;
}

public E get(int index) {
    rangeCheck(index);
    return (E) elementData[index];
}

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}

容量調整

public void trimToSize() {
    modCount++;
    int oldCapacity = elementData.length;
    if (size < oldCapacity)
        elementData = Arrays.copyOf(elementData, size);
}

總結

理解 ArrayList 與 Vector 的底層實現,有助於根據場景選擇適當集合類:單執行緒首選 ArrayList,多執行緒需同步則考慮 Vector 或同步包裝器。掌握擴容、刪除位移等細節,能寫出更高效、健壯的程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved