數組是 Java 最基礎的數據結構,但高效、優雅地操作數組往往被忽視。本文匯總 12 個高頻場景,對比傳統寫法與現代最佳實踐 (Java 8+ Stream、Apache Commons Lang、Guava),助你寫出更簡潔、高性能、可讀性更強的代碼。
// 靜態初始化 (推薦:類型推斷、簡潔)
String[] strs = {"a", "b", "c"};
int[] nums = {1, 2, 3, 4, 5};
// 動態指定長度
String[] empty = new String[5]; // 默認 null
// 匿名數組 (作為方法參數)
method(new String[]{"x", "y"});
避坑:new String[5]{...} 語法錯誤;基本類型數組默認值為 0/false,引用類型默認 null。
int[] arr = {1, 2, 3};
// 錯誤:直接打印輸出地址值 [I@15db9742
System.out.println(arr);
// 正確:Arrays.toString (一維) / deepToString (多維)
System.out.println(Arrays.toString(arr)); // [1, 2, 3]
// Java 8+ Stream 打印
Arrays.stream(arr).forEach(System.out::println);
String[] strs = {"a", "b", "c"};
// 核心:Arrays.asList 返回固定長度 List (底層數組視圖),不可增刪
List fixedList = Arrays.asList(strs);
// fixedList.add("d"); // 拋 UnsupportedOperationException
// 最佳實踐:拷貝到 ArrayList (可變)
List mutableList = new ArrayList<>(Arrays.asList(strs));
// 或 Stream (Java 8+)
List streamList = Arrays.stream(strs).collect(Collectors.toList());
String[] strs = {"a", "b", "c"};
// 方案 1:List.contains (轉換開銷小)
boolean has = Arrays.asList(strs).contains("a"); // true
// 方案 2:Stream (函數式)
boolean hasStream = Arrays.stream(strs).anyMatch("a"::equals);
// 方案 3:基本類型數組 (無裝箱開銷)
int[] nums = {1, 2, 3};
boolean hasInt = IntStream.of(nums).anyMatch(x -> x == 2);
int[] a = {1, 2};
int[] b = {3, 4};
// Apache Commons Lang (推薦:一行、可空安全)
int[] combined = ArrayUtils.addAll(a, b); // {1, 2, 3, 4}
// Java 8 Stream (無第三方依賴)
int[] combinedStream = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
// 手動 System.arraycopy (性能極致場景)
int[] manual = new int[a.length + b.length];
System.arraycopy(a, 0, manual, 0, a.length);
System.arraycopy(b, 0, manual, a.length, b.length);
7. 數組元素連接為字符串
String[] words = {"Apple", "Banana", "Cherry"}; // Apache Commons Lang StringUtils (推薦:處理 null、性能好) String joined = StringUtils.join(words, ", "); // "Apple, Banana, Cherry" // Java 8 StringJoiner / String.join String joinedJdk = String.join(", ", words); // 簡單場景首選 // StringJoiner 可自定義前綴/後綴 String custom = new StringJoiner(", ", "[", "]").add("A").add("B").toString(); // [A, B]8. List 轉數組
Listlist = Arrays.asList("a", "b", "c"); // 核心:toArray(new String[0]) - JDK 11+ 推薦 new String[0] (逃逸分析優化) String[] arr = list.toArray(new String[0]); // 指定大小 (舊版本優化,現已無必要) // String[] arr = list.toArray(new String[list.size()]); 9. 數組去重 (轉 Set)
String[] dup = {"a", "b", "a", "c", "b"}; // Stream distinct + toArray (保持數組類型) String[] unique = Arrays.stream(dup).distinct().toArray(String[]::new); // {"a","b","c"} // 基本類型 int[] uniqueInt = Arrays.stream(new int[]{1,2,1,3}).distinct().toArray();10. 數組反轉
int[] arr = {1, 2, 3, 4, 5}; // Apache Commons Lang (原地反轉,返回同數組引用) ArrayUtils.reverse(arr); // arr 變為 {5, 4, 3, 2, 1} // 手動雙指針 (無依賴、原地) for (int i = 0, j = arr.length - 1; i < j; i++, j--) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } // Stream 生成新數組 (函數式) int[] reversed = IntStream.rangeClosed(1, arr.length) .map(i -> arr[arr.length - i]) .toArray();11. 移除數組元素 (按值/按索引)
int[] arr = {1, 2, 3, 4, 5}; // Apache Commons Lang (按值移除首個匹配,返回新數組) int[] removed = ArrayUtils.removeElement(arr, 3); // {1, 2, 4, 5} // 按索引移除 int[] removedIdx = ArrayUtils.remove(arr, 2); // 移除索引 2 的元素 // Stream 過濾 (函數式,生成新數組) int[] filtered = Arrays.stream(arr).filter(x -> x != 3).toArray();12. 整數轉字節數組 (網絡傳輸/序列化核心)
int value = 0x01020304; // 16909060 // Java NIO ByteBuffer (標準、可指定字節序) byte[] bytes = ByteBuffer.allocate(4).putInt(value).array(); // 大端序 (網絡序) 默認: [1, 2, 3, 4] // 小端序: ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array() // 手動位運算 (無依賴、極致性能) byte[] manual = new byte[]{ (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value }; // Guava Ints.toByteArray (簡潔) // byte[] guava = Ints.toByteArray(value);總結:工具選型建議
| 場景 | 首選方案 | 備選方案 |
|---|---|---|
| 通用數組操作 (合併、反轉、移除、轉字節) | Apache Commons Lang ArrayUtils | 手動 System.arraycopy / 位運算 |
| 字符串連接 | JDK String.join / StringJoiner | Commons Lang StringUtils.join |
| 函數式處理 (過濾、映射、去重、查找) | Java 8+ Stream API (Arrays.stream/IntStream) | Guava Streams/Iterables |
| 基本類型性能敏感場景 | 原始循環 / IntStream / 手動位運算 | 避免裝箱 Integer[] |
核心原則:基本類型數組優先用基本類型流 (IntStream/LongStream/DoubleStream) 避免裝箱拆箱;引用類型數組盡享 Stream 函數式優雅;工具類方法名語義化 (addAll, removeElement) 降低認知負荷。