thinking in java 11——Arrays相关方法源码

来源:互联网 发布:java符号 编辑:程序博客网 时间:2024/05/20 07:36

System.arraycopy

.
1. 复制数组比for循环快的多,因为使用native本地方法实现的

//:Demoint[] i = new int[7];int[] j = new int[10];Arrays.fill(i, 47);Arrays.fill(j, 99);System.out.println("i = "+Arrays.toString(i));System.out.println("j = "+Arrays.toString(j));System.arraycopy(i, 0, j, 0, i.length);System.out.println("j = "+Arrays.toString(j));/**:~i = [47, 47, 47, 47, 47, 47, 47]j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99]j = [47, 47, 47, 47, 47, 47, 47, 99, 99, 99]*///:sourcepublic static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);/***可以复制基本类型数组或者对象数组,注:1.如果复制对象数组,那么只是*复制了对象的引用——而不是对象本身的拷贝;2.System.arraycopy()*不会执行自动包装和自动拆包,两个数组必须具有相同的确切类型*/


Arrays

.
1. equals

//:Demoint[] a1 = new int[10];int[] a2 = new int[10];Arrays.fill(a1, 47);Arrays.fill(a2, 47);System.out.println(Arrays.equals(a1, a2));String[] s1 = new String[4];Arrays.fill(s1, "hi");String[] s2 = {new String("hi"),new String("hi"),new String("hi"),new String("hi")};System.out.println(Arrays.equals(s1, s2));/**:~*true*true*///:source/**     * Returns <tt>true</tt> if the two specified arrays of ints are     * <i>equal</i> to one another.  Two arrays are considered equal if both     * arrays contain the same number of elements, and all corresponding pairs     * of elements in the two arrays are equal.  In other words, two arrays     * are equal if they contain the same elements in the same order.  Also,     * two array references are considered equal if both are <tt>null</tt>.<p>     *     * @param a one array to be tested for equality     * @param a2 the other array to be tested for equality     * @return <tt>true</tt> if the two arrays are equal     */    public static boolean equals(int[] a, int[] a2) {        if (a==a2)//指向地址相同返回true            return true;        if (a==null || a2==null)//鲁棒性            return false;        int length = a.length;        if (a2.length != length)//长度不相等返回false            return false;        for (int i=0; i<length; i++)//遍历比对值            if (a[i] != a2[i])                return false;        return true;    }/*===================================================*//**     * Returns <tt>true</tt> if the two specified arrays of Objects are     * <i>equal</i> to one another.  The two arrays are considered equal if     * both arrays contain the same number of elements, and all corresponding     * pairs of elements in the two arrays are equal.  Two objects <tt>e1</tt>     * and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null     * : e1.equals(e2))</tt>.  In other words, the two arrays are equal if     * they contain the same elements in the same order.  Also, two array     * references are considered equal if both are <tt>null</tt>.<p>     *     * @param a one array to be tested for equality     * @param a2 the other array to be tested for equality     * @return <tt>true</tt> if the two arrays are equal     */    public static boolean equals(Object[] a, Object[] a2) {        if (a==a2)//地址相同返回true            return true;        if (a==null || a2==null)//鲁棒性            return false;        int length = a.length;        if (a2.length != length)//判断长度            return false;        for (int i=0; i<length; i++) {//遍历比对值            Object o1 = a[i];            Object o2 = a2[i];            //鲁棒性            if (!(o1==null ? o2==null : o1.equals(o2)))                return false;        }        return true;    }

.
2. public static void fill():重载了多种类型

//:Demoint[] i = new int[7];Arrays.fill(i, 47);System.out.println(Arrays.toString(i));///~[47, 47, 47, 47, 47, 47, 47]//:source(以int[]为例)/**     * Assigns the specified int value to each element of the specified array     * of ints.     *     * @param a the array to be filled     * @param val the value to be stored in all elements of the array     */public static void fill(int[] a, int val) {        for (int i = 0, len = a.length; i < len; i++)            a[i] = val;}/**     * Assigns the specified long value to each element of the specified     * range of the specified array of longs.  The range to be filled     * extends from index <tt>fromIndex</tt>, inclusive, to index     * <tt>toIndex</tt>, exclusive.  (If <tt>fromIndex==toIndex</tt>, the     * range to be filled is empty.)     *     * @param a the array to be filled     * @param fromIndex the index of the first element (inclusive) to be     *        filled with the specified value     * @param toIndex the index of the last element (exclusive) to be     *        filled with the specified value     * @param val the value to be stored in all elements of the array     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or     *         <tt>toIndex &gt; a.length</tt>     */public static void fill(long[] a, int fromIndex, int toIndex, long val) {        rangeCheck(a.length, fromIndex, toIndex);        for (int i = fromIndex; i < toIndex; i++)            a[i] = val;}/**     * Checks that {@code fromIndex} and {@code toIndex} are in     * the range and throws an appropriate exception, if they aren't.     */private static void rangeCheck(int length, int fromIndex, int toIndex) {        if (fromIndex > toIndex) {            throw new IllegalArgumentException(                "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");        }        if (fromIndex < 0) {            throw new ArrayIndexOutOfBoundsException(fromIndex);        }        if (toIndex > length) {            throw new ArrayIndexOutOfBoundsException(toIndex);        }}/***可以看到fill方法实现很简单,就是循环复制,一般这个方法很少用,*用在生成测试数据有点用*/

.
3. sort:策略模式

//:Demoint[] a = {2,4,1,5,7,0,9,8};Arrays.sort(a);System.out.println(Arrays.toString(a));///:~[0, 1, 2, 4, 5, 7, 8, 9]//:source (int[])public static void sort(int[] a) {        DualPivotQuicksort.sort(a);//快排}/** *Sorts the specified array. * * @param a the array to be sorted */public static void sort(int[] a) {    sort(a, 0, a.length - 1);//排序}/**     * Sorts the specified range of the array.     *     * @param a the array to be sorted     * @param left the index of the first element, inclusive, to be sorted     * @param right the index of the last element, inclusive, to be sorted     *//*================================================快排思想:选取分割点t,将小于t和大于t的分别分在两端,然后按照相同的思想递归排下去,最后将排序好的小数组合并,详见博文快排=================================================*/public static void sort(int[] a, int left, int right) {    // Use Quicksort on small arrays(length < 286) if (right - left < QUICKSORT_THRESHOLD) {//小数组用快排      sort(a, left, right, true);//源代码太过于长,可自行查看DualPivotQuicksort      return;  } /*  * Index run[i] is the start of i-th run  * (ascending or descending sequence).  */ int[] run = new int[MAX_RUN_COUNT + 1]; int count = 0; run[0] = left;//初始取a[left]为分割点 // Check if the array is nearly sorted:最多轮询68次 for (int k = left; k < right; run[count] = k) {     if (a[k] < a[k + 1]) { // ascending         while (++k <= right && a[k - 1] <= a[k]);     } else if (a[k] > a[k + 1]) { // descending         while (++k <= right && a[k - 1] >= a[k]);         for (int lo=run[count]-1,hi=k;++lo<--hi;){//变换递增             int t=a[lo];a[lo] = a[hi]; a[hi] = t;         }     } else { // equal         for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {//超过33个数相等则直接DualPivotQuicksort             if (--m == 0) {                 sort(a, left, right, true);                 return;             }         }     }     /*      * The array is not highly structured,      * use Quicksort instead of merge sort.      */     if (++count == MAX_RUN_COUNT) {         sort(a, left, right, true);         return;     } } // Check special cases if (run[count] == right++) { // The last run contains one element     run[++count] = right; } else if (count == 1) { // The array is already sorted:已经有序     return; } /*  * Create temporary array, which is used for merging.  * Implementation note: variable "right" is increased by 1.  */ int[] b; byte odd = 0; for (int n = 1; (n <<= 1) < count; odd ^= 1); if (odd == 0) {     b = a; a = new int[b.length];     for (int i = left - 1; ++i < right; a[i] = b[i]); } else {     b = new int[a.length]; } // Merging for (int last; count > 1; count = last) {     for (int k = (last = 0) + 2; k <= count; k += 2) {         int hi = run[k], mi = run[k - 1];         for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {             if (q >= hi || p < mi && a[p] <= a[q]) {                 b[i] = a[p++];             } else {                 b[i] = a[q++];             }         }         run[++last] = hi;     }     if ((count & 1) != 0) {         for (int i = right, lo = run[count - 1]; --i >= lo;             b[i] = a[i]         );         run[++last] = right;     }     int[] t = a; a = b; b = t; }}/*===================================================*//**排序是依赖于比较进行的,一般对象实现比较需要实现Comparable<T>*接口,也可以实现comparator接口,前面章节会有关于这两个接口的介绍*///:sourcepublic static void sort(Object[] a) {        if (LegacyMergeSort.userRequested)            legacyMergeSort(a);        else            ComparableTimSort.sort(a);}/** To be removed in a future release. */private static void legacyMergeSort(Object[] a) {    Object[] aux = a.clone();    mergeSort(aux, a, 0, a.length, 0);//归并排序}/*====================================================归并排序思想:分治法=====================================================*/private static void mergeSort(Object[] src,                                  Object[] dest,                                  int low,                                  int high,                                  int off) {        int length = high - low;        // Insertion sort on smallest arrays        if (length < INSERTIONSORT_THRESHOLD) {            for (int i=low; i<high; i++)                for (int j=i; j>low &&                         ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)                    swap(dest, j, j-1);            return;        }        // Recursively sort halves of dest into src        int destLow  = low;        int destHigh = high;        low  += off;        high += off;        int mid = (low + high) >>> 1;        mergeSort(dest, src, low, mid, -off);        mergeSort(dest, src, mid, high, -off);        // If list is already sorted, just copy from src to dest.  This is an        // optimization that results in faster sorts for nearly ordered lists.        if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {            System.arraycopy(src, low, dest, destLow, length);            return;        }        // Merge sorted halves (now in src) into dest        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {            if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)                dest[i] = src[p++];            else                dest[i] = src[q++];        }    }/*=================ComparableTimSort=================*//*     * The next two methods (which are package private and static) constitute     * the entire API of this class.  Each of these methods obeys the contract     * of the public method with the same signature in java.util.Arrays.     */static void sort(Object[] a) {//ComparableTimSort          sort(a, 0, a.length);}static void sort(Object[] a, int lo, int hi) {        rangeCheck(a.length, lo, hi);        int nRemaining  = hi - lo;        if (nRemaining < 2)            return;  // Arrays of size 0 and 1 are always sorted        // If array is small, do a "mini-TimSort" with no merges        if (nRemaining < MIN_MERGE) {            int initRunLen = countRunAndMakeAscending(a, lo, hi);            binarySort(a, lo, hi, lo + initRunLen);            return;        }/*===================================================二分排序:折半插入排序===================================================*/@SuppressWarnings("fallthrough")    private static void binarySort(Object[] a, int lo, int hi, int start) {        assert lo <= start && start <= hi;        if (start == lo)            start++;        for ( ; start < hi; start++) {            @SuppressWarnings("unchecked")            Comparable<Object> pivot = (Comparable) a[start];            // Set left (and right) to the index where a[start] (pivot) belongs            int left = lo;            int right = start;            assert left <= right;            /*             * Invariants:             *   pivot >= all in [lo, left).             *   pivot <  all in [right, start).             */            while (left < right) {                int mid = (left + right) >>> 1;                if (pivot.compareTo(a[mid]) < 0)                    right = mid;                else                    left = mid + 1;            }            assert left == right;            /*             * The invariants still hold: pivot >= all in [lo, left) and             * pivot < all in [left, start), so pivot belongs at left.  Note             * that if there are elements equal to pivot, left points to the             * first slot after them -- that's why this sort is stable.             * Slide elements over to make room for pivot.             */            int n = start - left;  // The number of elements to move            // Switch is just an optimization for arraycopy in default case            switch (n) {                case 2:  a[left + 2] = a[left + 1];                case 1:  a[left + 1] = a[left];                         break;                default: System.arraycopy(a, left, a, left + 1, n);            }            a[left] = pivot;        }    }

.
4. binarySearch

//:Demoint[] a1 = {2,4,1,5,7,0,9,8};Arrays.sort(a1);System.out.println(Arrays.toString(a1));System.out.println(Arrays.binarySearch(a1,3));///:~找到时返回位置index,未找到返回返回值 = -(插入点)-1/***[0, 1, 2, 4, 5, 7, 8, 9]*-4*///:Sourcepublic static int binarySearch(int[] a, int key) {    return binarySearch0(a, 0, a.length, key);} // Like public version, but without range checks.    private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {        int low = fromIndex;        int high = toIndex - 1;        while (low <= high) {//当未找到时一直折半下去            int mid = (low + high) >>> 1;//无符号右移            int midVal = a[mid];            if (midVal < key)                low = mid + 1;            else if (midVal > key)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found.***    }/*=================================================*/    public static int binarySearch(Object[] a, Object key) {        return binarySearch0(a, 0, a.length, key);    }// Like public version, but without range checks.    private static int binarySearch0(Object[] a, int fromIndex, int toIndex, Object key) {        int low = fromIndex;        int high = toIndex - 1;        while (low <= high) {            int mid = (low + high) >>> 1;            /*需要实现comparable接口,当使用comparator时需要作为参数穿进去,可以自行查阅源码*/            Comparable midVal = (Comparable)a[mid];            int cmp = midVal.compareTo(key);            if (cmp < 0)                low = mid + 1;            else if (cmp > 0)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found.    }

未完待续~

0 0
原创粉丝点击