Java 陣列是固定大小、同質型別的資料結構,雖然 Collection 框架更靈活,但陣列在效能敏感、底層互操、原始型別處理上仍不可或缺。java.util.Arrays 提供豐富靜態方法,配合反射 API 可實現陣列與 Collection 的無縫轉換。
import java.util.Arrays;
int[] scores = {85, 92, 78, 96, 88};
Arrays.sort(scores); // 升序,原地排序(Dual-Pivot Quicksort)
// 結果:[78, 85, 88, 92, 96]
// 指定範圍排序
Arrays.sort(scores, 1, 4); // 只排索引 1~3
// 結果:[78, 85, 88, 92, 96] (此例無變化)
String[] names = {"Bob", "Alice", "Charlie"};
Arrays.sort(names); // 自然順序 (Comparable)
// 結果:["Alice", "Bob", "Charlie"]
// 自定義比較器:長度降序
Arrays.sort(names, (a, b) -> Integer.compare(b.length(), a.length()));
// 結果:["Charlie", "Alice", "Bob"] (長度 7, 5, 3)
// 大陣列多核排序,閾值約 8192 元素
Arrays.parallelSort(largeArray);
前提:陣列必須已排序
int[] sorted = {10, 20, 30, 40, 50};
int idx = Arrays.binarySearch(sorted, 30); // 找到 → 返回索引 2
int idx2 = Arrays.binarySearch(sorted, 35); // 未找到 → 返回 (-(插入點) - 1) = -3
// 插入點計算
int insertPos = -idx2 - 1; // = 2,表示應插在索引 2 (30 和 40 之間)
String[] byLength = {"a", "bb", "ccc", "dddd"};
// 必須用相同比較器排序過
Arrays.sort(byLength, Comparator.comparingInt(String::length));
int pos = Arrays.binarySearch(byLength, "xx", Comparator.comparingInt(String::length));
// 找長度 2 的字串位置
// int[] → Integer[]
int[] primitive = {1, 2, 3};
Integer[] boxed = new Integer[primitive.length];
for (int i = 0; i < primitive.length; i++) {
boxed[i] = primitive[i]; // 自動裝箱
}
// Integer[] → int[]
Integer[] boxed2 = {4, 5, 6};
int[] primitive2 = new int[boxed2.length];
for (int i = 0; i < boxed2.length; i++) {
primitive2[i] = boxed2[i]; // 自動拆箱
}
int[] prim = {1, 2, 3};
Integer[] boxed = Arrays.stream(prim).boxed().toArray(Integer[]::new);
Integer[] boxed2 = {4, 5, 6};
int[] prim2 = Arrays.stream(boxed2).mapToInt(Integer::intValue).toArray();
// Apache Commons Lang
int[] prim = ArrayUtils.toPrimitive(new Integer[]{1,2,3});
Integer[] boxed = ArrayUtils.toObject(new int[]{1,2,3});
// Guava
int[] prim = Ints.toArray(List.of(1,2,3));
List list = Ints.asList(1,2,3);
String[] arr = {"A", "B", "C"};
List list = Arrays.asList(arr); // 返回固定大小 List 視圖
// 特性:
list.set(1, "Z"); // 允許修改元素 → 原陣列同步變化
// list.add("D"); // 拋出 UnsupportedOperationException
// list.remove(0); // 拋出 UnsupportedOperationException
// Java 9+
List modifiable = new ArrayList<>(List.of(arr));
// Java 8
List modifiable = new ArrayList<>(Arrays.asList(arr));
// Guava
List modifiable = Lists.newArrayList(arr);
List list = List.of("X", "Y", "Z");
// 正確方式:傳入型別陣列
String[] arr1 = list.toArray(new String[0]); // JVM 優化:新建精確大小陣列
String[] arr2 = list.toArray(String[]::new); // Java 11+ 方法引用寫法
// 錯誤方式:toArray() 返回 Object[],無法轉型為 String[]
// String[] bad = (String[]) list.toArray(); // ClassCastException
適用於運行期型別未知的通用工具開發
import java.lang.reflect.Array;
public class ArrayUtils {
/** 通用陣列複製並轉型 */
@SuppressWarnings("unchecked")
public static T[] copyAndCast(Object srcArray, Class componentType) {
if (srcArray == null || !srcArray.getClass().isArray()) return null;
int len = Array.getLength(srcArray);
T[] dest = (T[]) Array.newInstance(componentType, len);
for (int i = 0; i < len; i++) {
dest[i] = componentType.cast(Array.get(srcArray, i));
}
return dest;
}
/** 建立指定型別、長度的陣列 */
public static Object newArray(Class> componentType, int length) {
return Array.newInstance(componentType, length);
}
}
// 規則二維陣列
int[][] matrix = new int[3][4]; // 3 行 4 列
// 不規則陣列
int[][] jagged = {
{1, 2},
{3, 4, 5, 6},
{7}
};
int[][] original = {{1,2}, {3,4}};
// 錯誤:淺複製
int[][] shallow = original.clone(); // 內層陣列共用引用
// 正確:深度複製
int[][] deep = new int[original.length][];
for (int i = 0; i < original.length; i++) {
deep[i] = original[i].clone(); // 或 Arrays.copyOf(original[i], original[i].length)
}
int[][] data = largeMatrix;
// 計算每行總和
int[] rowSums = Arrays.stream(data)
.parallel()
.mapToInt(row -> Arrays.stream(row).sum())
.toArray();
| 操作 | 時間複雜度 | 空間複雜度 | 備註 |
|---|---|---|---|
| Arrays.sort (基本型別) | O(n log n) | O(1) | Dual-Pivot Quicksort,原地 |
| Arrays.sort (物件) | O(n log n) | O(n) | TimSort,穩定,需輔助陣列 |
| Arrays.binarySearch | O(log n) | O(1) | 前提:已排序 |
| Arrays.asList | O(1) | O(1) | 視圖,無複製 |
| List.toArray | O(n) | O(n) | 新建陣列複製 |
| Stream 轉換 | O(n) | O(n) | 中間物件開銷較大 |
List list = Arrays.asList(new int[]{1,2}); // size() == 1 Object[] objArr = new String[10]; objArr[0] = new Integer(1); // 運行期 ArrayStoreExceptionparallelSort 反而較慢List 不合法,必須用 List 或第三方庫掌握 Arrays 工具類、Stream API、反射陣列操作與 Collection 互轉技巧,能讓你在處理大量資料、高效能計算、底層庫開發時遊刃有餘。原則:能用基本型別陣列就不用包裝型別,能用 Arrays 靜態方法就不用手寫迴圈,能用 Stream 表達意圖就不用命令式迴圈。