java.util.Arrays 快速使用介紹

程序猿阿朗發表於2024-03-06

在 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),不過是簡單的一個呼叫,卻讓你的陣列輸出從一串地址,變成了清晰可辨的字元。

複製陣列

要複製一個新的陣列麼?copyOfcopyOfRange 給你全方位的選擇:

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));

copyOfcopyOfRange,無異於為陣列之尺,想要複製前 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 教程
本文原發於公眾號:程式猿阿朗

相關文章