在 Java 中,java.util.Arrays
類提供的多種陣列操作功能,可以有效地執行各種陣列相關的操作,使得陣列處理變得簡單和高效。
列印陣列
String[] arr = new String[] {"a", "b", "c", "d"};
System.out.println(Arrays.toString(arr)); // 輸出 [a, b, c, d]
Arrays.toString(arr)
,不過是簡單的一個呼叫,卻讓你的陣列輸出從一串地址,變成了清晰可辨的字元。
複製陣列
要複製一個新的陣列麼?copyOf
和 copyOfRange
給你全方位的選擇:
String[] arr = new String[] {"a", "b", "c", "d"};
String[] copyOf2 = Arrays.copyOf(arr, 2); // [a, b]
System.out.println(Arrays.toString(copyOf2));
String[] copyOfRange = Arrays.copyOfRange(arr, 1, 3); // [b, c]
System.out.println(Arrays.toString(copyOfRange));
String[] copyOf10 = Arrays.copyOf(arr, 10); // [a, b, c, d, null, null, null, null, null, null]
System.out.println(Arrays.toString(copyOf10));
這 copyOf
,copyOfRange
,無異於為陣列之尺,想要複製前 N 個元素,使用 copyOf
,想要取其中一段,使用 copyOfRange
。
注意:若範圍大於原陣列,多出位置以 null 填充。
填充陣列
String[] arr = new String[5];
Arrays.fill(arr, "java");
System.out.println(Arrays.toString(arr)); // [java, java, java, java, java]
如若陣列空空如也,可用 Arrays.fill(arr, "str")
將它填滿。每一個元素,都被賦予相同的值。
也可以使用 Arrays.setAll
填充,它允許傳入一個函式,生成填充值。
// 生成 100以內的 隨機數
IntFunction<Integer> intFunction = i -> new Random().nextInt(100);
Integer[] intArr = new Integer[5];
Arrays.setAll(intArr, intFunction);
System.out.println(Arrays.toString(intArr));
// output:[29, 17, 18, 11, 85]
陣列比較
資料比較有兩種方式,一是使用 Arrays.equals
,二是使用 Arrays.hashCode
。
Arrays.equals
String[] arr = new String[] {"a", "b", "c", "d"};
Object[] arr1 = new Object[] {arr, new String[] {"a", "b", "c", "d"}};
Object[] arr2 = new Object[] {arr, arr};
System.out.println(Arrays.equals(arr1, arr2)); // false
System.out.println(Arrays.deepEquals(arr1, arr2)); // tue
如果是一維陣列比較,直接 Arrays.equals
比較沒有問題。如果是多維陣列,Arrays.equals
並不會比較子陣列中的元素值,此時需要使用deepEquals
比較。
Arrays.hashCode
String[] arr = new String[] {"a", "b", "c", "d"};
Object[] arr2 = new Object[] {arr, arr};
System.out.println(Arrays.hashCode(arr2));
System.out.println(Arrays.deepHashCode(arr2));
arr[0] = null;
System.out.println(Arrays.hashCode(arr2));
System.out.println(Arrays.deepHashCode(arr2));
元素可能會變,如何捕捉這一瞬間的改變?hashCode()
,deepHashCode()
,便是這捕風捉影的法寶。hashCode
方法會根據陣列元素值計算出一個數字,如果元素值發生改變,則數字改變。但是同樣對於多維數字,在計算數字時不會計運算元陣列中的元素,這種情況應該使用 deepHashCode
判斷。
輸出:
-2117384671
125140001
-2117384671
32668737
陣列排序
// 生成 100以內的 隨機數
IntFunction<Integer> intFunction = i -> new Random().nextInt(100);
Integer[] intArr = new Integer[5];
Arrays.setAll(intArr, intFunction);
System.out.println(Arrays.toString(intArr));
// output: [18, 31, 86, 59, 43]
Arrays.sort(intArr);
System.out.println(Arrays.toString(intArr));
// output: [18, 31, 43, 59, 86]
Arrays.sort
方法可以將元素排序。而 parallelSort()
可以併發排序,但是在資料量比較小的情況下,Arrays.sort
可能效率更高。
二分查詢
二分搜尋可以快速找到陣列中的指定元素的利器。
Integer[] intArr = new Integer[] {2, 3, 4, 5, 6, 7, 8, 9};
int index = Arrays.binarySearch(intArr, 3);
System.out.println("index:"+index);
System.out.println(intArr[index]);
注意事項:使用
binarySearch()
前確保陣列是排序過的,否則結果將不可預知。
陣列轉 Stream
Java 8 引入的 Stream API 讓陣列操作更加現代化,可以鏈式操作。使用 Arrays.stream
可以讓陣列共享這一便利。
Integer[] intArr = new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
System.out.println(Arrays.stream(intArr).count()); // 10
ToIntFunction toIntFunction = i -> (int)i;
System.out.println(Arrays.stream(intArr).mapToInt(toIntFunction).sum());// 45
陣列轉換
如果你想把陣列轉成 List 怎麼辦?Arrays.asList()
就是你需要的。
String[] arr = new String[] {"a", "b", "c", "d"};
List<String> list = Arrays.asList(arr);
System.out.println(list); // 輸出 [a, b, c, d]
// list.add("e"); 報錯
注意事項:asList()
返回的列表不支援增刪操作,它和原始陣列是共享資料的。
並行字首計算
使用 parallelPrefix
函式並行地累積給定陣列中的每個元素。對於大型陣列,並行字首計算通常比順序迴圈更有效。
示例:每一個元素轉換成當前以及之前所有元素的和。
Integer[] intArr = new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Arrays.parallelPrefix(intArr, (left, right) -> left + right);
System.out.println(Arrays.toString(intArr));
輸出:[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
總結
文章介紹了Java中java.util.Arrays
類提供的多種陣列操作功能,展示了其強大且多樣的用途。可以有效地執行各種陣列相關的操作,使得陣列處理變得簡單和高效。
本文 Github.com/niumoo/JavaNotes倉庫已經收錄。
本文原發於網站:Java Arrays 教程
本文原發於公眾號:程式猿阿朗