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 > toIndex</tt> * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or * <tt>toIndex > 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
- thinking in java 11——Arrays相关方法源码
- Thinking in Java之集合相关整理(源码分析)
- Thinking in Java 2: Arrays.toString vs. Arrays.deepToString
- Thinking in Java方法签名
- Thinking in java-11
- 学习总结-Thinking In Java Chapter 16 arrays
- thinking in java——Generics
- Thinking in java ——数组
- 引言——Thinking-in-Java
- 《Thinking in Java》——final关键字
- thinking in java——操作符
- thinking in java——复用类
- thinking in java——多态
- thinking in java——接口
- thinking in java——内部类
- thinking in java——持有对象
- Thinking in Java——final关键字
- Thinking in Android — Java入门 (1)
- 最近打算学习下flash开发,搭建一个flascc的环境,遇到了点问题
- Python计算斐波那契数列
- LogisticRegression
- STL学习记录(八)Sets、Multisets
- 二分归并排序
- thinking in java 11——Arrays相关方法源码
- Google MapReduce读后感
- OpenGL 中常用的 GLUT 函数库
- 文件名或路径太长导致没法移动或复制
- hdu 5046 airport DLX可重复覆盖
- Swing线程实现进度条的更新
- 线程同步和线程通信
- 新书:锋利的SQL(第2版)开始发售及代码下载
- 英朗面试题2015-05-22