Arrays工具類
和Collections 一樣,主要是提供了對集合的一些特殊操作或者說是擴充套件了集合的操作方法,Arrays類位於 java.util 包中,主要包含了運算元組的各種方法,其實我們知道其他的一些集合例如List、Set 這些集合類還是提供了很多方法的,但是陣列它是不屬於集合體系下的,它是透過[] 進行標識的,它沒有提供給使用者可操作的任何方法,只提供了一個length 屬性
如果你直接去看去看這個類的話,你會發現這個類提供的方法特別多就像下面這樣,但是你要是仔細看的話,就會發現其實很多方法都是過載方法,針對不同型別的陣列提供了不同的方法
下面我們就看一下到底有哪些不同的方法,下面就是主要的方法,後面我們針對這些方法進行講解
asList(T... a) binarySearch( Object[] a, Object key)copyOf(Object[] original, int newLength) copyOfRange(Object[] original, int from, int to) deepEquals(Object[] a1, Object[] a2)deepHashCode(Object a[]) deepToString(Object[] a) deepToString(Object[] a, StringBuilder buf, Set<Object[]> dejaVu) {equals(Object[] a, Object[] a2)fill(Object[] a, Object val)hashCode(char a[])legacyMergeSort(Object[] a) parallelPrefix(Object[] array, Object op)parallelSetAll(Object[] array, IntToObjectFunction generator) parallelSort(Object[] a) setAll(Object[] array, IntToObjectFunction generator)sort(Object[] a)spliterator(Object[] array) spliterator(Object[] array, int startInclusive, int endExclusive)stream(Object[] array)stream(Object[] array, int startInclusive, int endExclusive) swap(Object[] x, int a, int b)toString(Object[] a)複製程式碼
asList(T ... a)將陣列或者是可變引數轉化為List
剛接觸 Java 技術的開發人員可能不知道,Java 語言最初包括陣列,是為了應對上世紀 90 年代初期 C++ 開發人員對於效能方面的批評。從那時到現在,我們已經走過一段很長的路,如今,與 Java Collections 庫相比,陣列不再有效能優勢。
例如,若要將陣列的內容轉儲到一個字串,需要迭代整個陣列,然後將內容連線成一個 String ;而 Collections 的實現都有一個可用的 toString() 實現,可以直接使用。除少數情況外,好的做法是儘快將遇到的任何陣列轉換成集合。
@Testpublic void asList(){ List<String> list = Arrays.asList(new String[]{"a", "b", "c"}); List<String> list2 = Arrays.asList("a","b","c"); System.out.println(list); System.out.println(list2);}// 輸出結果[a, b, c][a, b, c]複製程式碼
注意,返回的 List 是不可修改的,所以如果嘗試向其中新增新元素將丟擲一個 UnsupportedOperationException 。
而且,由於 Arrays.asList() 使用 可變 引數表示新增到 List 的元素,所以還可以使用它輕鬆地用以 new 新建的物件建立 List 。
sort()對陣列中的元素進行排序
sort(Object[]) 按照升序,對全部元素進行排序
@Testpublic void sort() { int[] nums = {2, 5, 0, 4, 6, -10}; Arrays.sort(nums); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果-10 0 2 4 5 6 複製程式碼
sort(Object[] array, int from, int to) 按照升序,對指定範圍內的元素進行排序
@Testpublic void sort() { int[] nums = {2, 5, 0, 4, 6, -10}; Arrays.sort(nums,0,4); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果0 2 4 5 6 -10 複製程式碼
Arrays.sort(nums, new Comparator() ) 使用Comparator 指定排序方向
升序
@Testpublic void sort() { Integer[] nums = {2, 5, 0, 4, 6, -10}; Arrays.sort(nums, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果-10 0 2 4 5 6 複製程式碼
降序
@Testpublic void sort() { Integer[] nums = {2, 5, 0, 4, 6, -10}; Arrays.sort(nums, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } }); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果6 5 4 2 0 -10 複製程式碼
fill(Object[] a, Object val)
可以為陣列元素填充相同的值
@Testpublic void fill() { int[] nums = {2, 5, 0, 4, 6, -10}; Arrays.fill(nums, 1); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果1 1 1 1 1 1複製程式碼
Arrays.fill(Object[] array,int from,int to,Object object) 可以為指定範圍內的元素填充相同的值
@Testpublic void fill() { int[] nums = {2, 5, 0, 4, 6, -10}; Arrays.fill(nums, 1,3,100); for (int i : nums) { System.out.print(i + " "); }}// 輸出結果2 100 100 4 6 -10 複製程式碼
toString(Object[] array)
返回陣列的字串形式,因為預設輸出的時候是記憶體地址
@Testpublic void toStr() { int[] nums = {2, 5, 0, 4, 6, -10}; System.out.println(nums); System.out.println(Arrays.toString(nums));}// 輸出結果[I@587c290d[2, 5, 0, 4, 6, -10]複製程式碼
deepToString(Object[][] arrays)
返回多維陣列的字串形式
@Testpublic void deepToString() { int[][] nums = {{2, 5, 0, 4, 6, -10},{2, 5, 0, 4, 6, -10}}; System.out.println(nums); System.out.println(Arrays.deepToString(nums));}// 輸出結果[[I@587c290d[[2, 5, 0, 4, 6, -10], [2, 5, 0, 4, 6, -10]]複製程式碼
binarySearch(Object[] a, Object key)採用二分查詢方式,查詢某個特定的key,如果找到返回下標,找不到則返回-1,需要注意的是二分查詢要求輸入是有序的
無序的輸入
@Testpublic void binarySearch() { int bytes = Arrays.binarySearch(new byte[]{6,3,7,9,1,4,5,10}, (byte) 1); System.out.println(bytes);}// 輸出結果-1複製程式碼
可以看出當我們的輸入是無序的時候,查詢是不準確的,例如 上面的1 是存在的,但是卻沒有找到
有序的輸入
@Testpublic void binarySearch() { int bytes = Arrays.binarySearch(new byte[]{1,2,3,4,5,6,7}, (byte) 3); System.out.println(bytes);}// 輸出結果2複製程式碼
copyOf(object[] original, int newLength)
把陣列複製到另一個數組中並返回結果,我們先看一下這個方法的實現,其實我們看到底層是呼叫的 System.arraycopy 來實現的
public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; // Math.min(original.length, newLength) 是要複製的長度 System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy;}複製程式碼
newLength 指的是新陣列的長度,如果新陣列的長度大於要複製的陣列的長度,空的位置預設值來填充
@Testpublic void copyOf() { int[] ints = Arrays.copyOf(new int[]{1, 2, 3}, 10); System.out.println(Arrays.toString(ints)); }// 輸出結果[1, 2, 3, 0, 0, 0, 0, 0, 0, 0]複製程式碼
新陣列的長度小於老陣列的長度,則複製對應位置的資料
@Testpublic void copyOf() { int[] ints = Arrays.copyOf(new int[]{1, 2, 3}, 10); System.out.println(Arrays.toString(ints)); ints = Arrays.copyOf(new int[]{1, 2, 3}, 2); System.out.println(Arrays.toString(ints));}// 輸出結果[1, 2]複製程式碼
copyOfRange
我們還是先看一下這個方法 的實現,同樣還是藉助System.arraycopy 實現的
public static int[] copyOfRange(int[] original, int from, int to) { int newLength = to - from; if (newLength < 0) throw new IllegalArgumentException(from + " > " + to); int[] copy = new int[newLength]; // 特定範圍是透過Math.min(original.length - from, newLength)來實現的 System.arraycopy(original, from, copy, 0,Math.min(original.length - from, newLength)); return copy;}複製程式碼
@Testpublic void copyOfRange() { int[] ints = Arrays.copyOfRange(new int[]{9, 8, 7,6,5,4,3,2,1}, 0, 5); System.out.println(Arrays.toString(ints));}// 輸出結果[9, 8, 7, 6, 5]複製程式碼
parallelPrefix
使用平行計算,並對陣列做計算的功能,由於是一個函式式介面,可以作lambda表示式
@Testpublic void parallelPrefix() { int[] ints = {1, 2, 3, 4, 5}; //K表示陣列第一個值,也就是0號索引,V代表K的下一個索引值,兩個索引的值相加 Arrays.parallelPrefix(ints,(K,V)-> K+V); //輸出為[1, 3, 6, 10, 15]:流程是1和2相加為3,3和3相加為6,6和4相加為10...以此往後類推 System.out.println(Arrays.toString(ints)); int[] Ints = {5,4,3,2,1,0}; //從1號索引到5號索引之間開始相加數值 Arrays.parallelPrefix(Ints,1,5,(K,V) -> K + V); System.out.println(Arrays.toString(Ints)); //輸出為[5, 4, 7, 9, 10, 0]}複製程式碼
parallelSort使用並行排序+合併排序演算法對陣列進行排序*
@Testpublic void parallelSort() { int[] ints = {2, 3, 4, 5, 1}; Arrays.parallelSort(ints); //輸出為:[1, 2, 3, 4, 5] System.out.println(Arrays.toString(ints)); int[] Ints = {2, 3, 4, 5, 1,6,8,7}; //從1到7號索引之間進行排序 Arrays.parallelSort(Ints,1,7); //輸出為:[2, 1, 3, 4, 5, 6, 8, 7] System.out.println(Arrays.toString(Ints));}複製程式碼
stream
Java 中的集合提供了stream 操作,但是陣列並沒有,所以在這個工具類中提供了相應的方法,我們看到這個方法是1.8 才加進來的
/** * Returns a sequential {@link IntStream} with the specified array as its * source. * * @param array the array, assumed to be unmodified during use * @return an {@code IntStream} for the array * @since 1.8 */public static IntStream stream(int[] array) { return stream(array, 0, array.length);}複製程式碼
@Testpublic void stream() { int[] ints = {1, 2, 3,4,5,6,7}; IntStream stream = Arrays.stream(ints); //呼叫流count方法計算資料總數 System.out.println(stream.count()); //從0-3號索引區間開始計算 IntStream stre = Arrays.stream(ints, 0, 3); System.out.println(stre.count());}複製程式碼
總結關於陣列的複製底層呼叫的是 System.arraycopy,所以我們除了使用Arrays工具類提供的兩個複製方法,也可以使用System.arraycopy 方法List、Set 等這些集合類在Java中提供了很多可以操作方法,但是陣列它是不屬於集合體系下的,它是透過[] 進行標識的,它沒有提供給使用者可操作的任何方法,只提供了一個length 屬性,所以Arrays工具類提供了很多的方法可以方便的讓我們運算元組