Java 源码--Arrays
前言
數組比較特殊,一個數組屬于一個對象,但是它的創建方式卻不同于一般對象。
Java中的數組創建數組有以下三種方式:
// 第一種 int[] array = new int[5]; // 第二種 int[] array = {1, 2, 3, 4, 5}; // 第三種 int[] array = new int[]{1, 2, 3, 4, 5};判斷數組是否屬于一個對象可使用下列語句:
System.out.println(new int[2] instanceof Object);源碼分析
接下來我們就來看一下對數據進行操作的工具類Arrays。
Arrays源代碼看似很多,其實核心方法只有幾個,Arrays給每種數據類型都提供了方法。
sort()
sort()方法有兩種實現。第一種使用雙軸快速排序算法。
public static void sort(int[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); }第二種根據系統屬性設置使用舊的歸并排序算法或者帶比較的分區排序算法。
public static void sort(Object[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);if (LegacyMergeSort.userRequested)legacyMergeSort(a, fromIndex, toIndex);elseComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0); }parallelSort()
parallelSort()是Java8新增的并行排序算法,基于fork/join框架。PS:Fork/Join框架是Java7提供的一個用于并行執行任務的框架,是一個把大任務分割成若干個小任務,最終匯總每個小任務結果后得到大任務結果的框架。
public static void parallelSort(int[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);int n = toIndex - fromIndex, p, g;if (n <= MIN_ARRAY_SORT_GRAN ||(p = ForkJoinPool.getCommonPoolParallelism()) == 1)DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);elsenew ArraysParallelSortHelpers.FJInt.Sorter(null, a, new int[n], fromIndex, n, 0,((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?MIN_ARRAY_SORT_GRAN : g).invoke(); }ArraysParallelSortHelpers類中源碼有些復雜,就先不探究它了。我們來比較一下sort()和parallelSort()的性能。從數組長度10開始,到長度100000000,打印倆個鬧鐘功能排序消耗的時間。
public static void main(String[] args) {for (int i = 10; i <= 100000000; i *= 10) {test(i);} }static void test(int limit) {IntStream intStream = new Random().ints(limit);int[] arr1 = intStream.toArray();int[] arr2 = Arrays.copyOf(arr1, arr1.length);long t1 = System.currentTimeMillis();Arrays.sort(arr1);long t2 = System.currentTimeMillis();Arrays.parallelSort(arr2);long t3 = System.currentTimeMillis();System.out.println("數組長度:" + limit + "\tsort:" + (t2 - t1) + "ms\tparallelSort:" + (t3 - t2) + "ms"); }輸出結果:
數組長度:10 sort:1ms parallelSort:0ms 數組長度:100 sort:0ms parallelSort:0ms 數組長度:1000 sort:0ms parallelSort:1ms 數組長度:10000 sort:3ms parallelSort:10ms 數組長度:100000 sort:16ms parallelSort:22ms 數組長度:1000000 sort:105ms parallelSort:48ms 數組長度:10000000 sort:1235ms parallelSort:412ms 數組長度:100000000 sort:10194ms parallelSort:4820ms可以看出,從長度1000000開始,并行排序消耗的時間比串行排序消耗的時間變短。所以,在一般情況下,使用sort()方法即可,當數組長度很大時,使用parallelSort()方法。
parallelPrefix()
串行計算數組累加值。
public static <T> void parallelPrefix(T[] array, BinaryOperator<T> op) {Objects.requireNonNull(op);if (array.length > 0)new ArrayPrefixHelpers.CumulateTask<>(null, op, array, 0, array.length).invoke(); }binarySearch()
二分查找。使用的前提是數組是已經從小到大排好序的。
public static int binarySearch(long[] a, long key) {return binarySearch0(a, 0, a.length, key); }private static int binarySearch0(long[] a, int fromIndex, int toIndex,long key) {int low = fromIndex;int high = toIndex - 1;while (low <= high) {int mid = (low + high) >>> 1;long midVal = a[mid];if (midVal < key)low = mid + 1;else if (midVal > key)high = mid - 1;elsereturn mid; // key found}return -(low + 1); // key not found. }equals()
判斷兩個數組是否相等,包括基本類型、對象的判等。基本類型的判等就是先判斷結構上是否相等,然后調用ArraysSupport類的mismatch()方法判斷內容的相等性。
public static boolean equals(long[] a, long[] a2) {if (a==a2)return true;if (a==null || a2==null)return false;int length = a.length;if (a2.length != length)return false;return ArraysSupport.mismatch(a, a2, length) < 0; }fill()
填充。
public static void fill(long[] a, long val) {for (int i = 0, len = a.length; i < len; i++)a[i] = val; }copyOf()和copyOfRange()
復制和復制指定范圍。
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {@SuppressWarnings("unchecked")T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]: (T[]) Array.newInstance(newType.getComponentType(), newLength);System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));return copy; }public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {int newLength = to - from;if (newLength < 0)throw new IllegalArgumentException(from + " > " + to);@SuppressWarnings("unchecked")T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]: (T[]) Array.newInstance(newType.getComponentType(), newLength);System.arraycopy(original, from, copy, 0,Math.min(original.length - from, newLength));return copy; }asList()
返回List。這里返回的ArrayList是Arrays中的一個靜態內部類。
public static <T> List<T> asList(T... a) {return new ArrayList<>(a); }hashCode()
返回哈希值。
public static int hashCode(long a[]) {if (a == null)return 0;int result = 1;for (long element : a) {int elementHash = (int)(element ^ (element >>> 32));result = 31 * result + elementHash;}return result; }toString()
返回字符串。
public static String toString(long[] a) {if (a == null)return "null";int iMax = a.length - 1;if (iMax == -1)return "[]";StringBuilder b = new StringBuilder();b.append('[');for (int i = 0; ; i++) {b.append(a[i]);if (i == iMax)return b.append(']').toString();b.append(", ");} }總結
以上是生活随笔為你收集整理的Java 源码--Arrays的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员食品营养(1)-面包基础
- 下一篇: 23种经典设计模式都有哪些,如何分类?J