Array - Java 基礎數組
三種聲明方式
int[] a = new int[10]; // 推薦:類型在前,語義清晰
int a[] = new int[10]; // C 風格,不推薦
int[] a = {1, 2, 3, 4}; // 靜態初始化
核心特徵
- 固定長度:創建時指定大小,不可變
- 同類型元素:只能存儲同一數據類型
- 無額外方法:僅有
length 屬性,無 add/remove 等操作
- 未重寫 equals/hashCode:
b.equals(c) 比較引用而非內容
數組比較正確姿勢
int[] b = {1, 2};
int[] c = {1, 2};
System.out.println(b.equals(c)); // false - 引用比較
System.out.println(Arrays.equals(b, c)); // true - 內容比較
// 或手動實現
public static boolean isEquals(int[] b, int[] c) {
if (b.length != c.length) return false;
for (int i = 0; i < b.length; i++) if (b[i] != c[i]) return false;
return true;
}
二維數組與變長數組
int[][] normal = new int[2][3]; // 固定 2行3列
int[][] ragged = new int[2][]; // 變長:第一維固定,第二維可變
ragged[0] = new int[2];
ragged[1] = new int[3];
ArrayList - 動態數組
聲明與泛型
ArrayList list = new ArrayList(10); // 原始類型,可存異構對象
ArrayList<Integer> list1 = new ArrayList<>(); // 泛型,類型安全
核心方法
list.add(1);
list.add(2);
list.remove(1); // 刪除索引1元素
Object[] arr = list.toArray(); // 轉數組
list.contains(4); // 是否包含
list.size(); // 實際元素數
list.get(0); // 按索引獲取
list.trimToSize(); // 縮容至實際大小,釋放內存
深度對比:Array vs ArrayList
| 維度 | Array | ArrayList |
| 本質 | JVM 原生類型,連續內存 | 封裝 Object[],動態擴容 |
| 泛型支持 | 不支持(卻有協變風險) | 完整泛型支持,類型安全 |
| 元素類型 | 基本類型/引用類型均可 | 僅引用類型(基本類型自動裝箱) |
| 長度可變 | 固定不可變 | 動態擴容(1.5倍/2倍策略) |
| 性能特點 | 訪問最快,無額外開銷 | 裝箱/拆箱開銷,擴容複製開銷 |
| 查找效率 | O(1) 索引訪問 | O(1) 索引,但 contains/indexOf 為 O(n) 線性掃描 |
| 適用場景 | 大小固定、高性能、基本類型 | 大小不定、頻繁增刪、業務開發首選 |
底層實現洞察
// ArrayList 核心字段
transient Object[] elementData; // 實際存儲數組
private int size; // 邏輯大小
// 擴容機制 (JDK 8)
public boolean add(E e) {
ensureCapacityInternal(size + 1);
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++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍擴容
if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
性能優化建議
- 預估大小:`new ArrayList<>(預估大小)` 減少擴容次數
- 基本類型用數組:避免裝箱拆箱,如 `int[]` 優於 `ArrayList`
- 頻繁查找用 Map/Set:`ArrayList.contains()` 為 O(n),大數據量改用 `HashSet` O(1)
- 只讀場景:`Collections.unmodifiableList()` 或 `List.of()` (JDK 9+)