Java Arrays源码阅读笔记
来自包 java.utils.Arrays 文字与代码对应关心:学习理解的文字在源代码的下方 |
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
-
最小数组长度,低于该长度,并行排序算法将不会进一步划分排序任务。使用较小的大小通常会导致任务之间的内存竞争,从而使并行加速变得不太可能。默认是2^13 = 8192个元素长度。
private Arrays() {}
-
取消默认构造函数,确保不可实例化。
private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > arrayLength) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
-
检查数组的索引范围是否正常,如果异常就抛出异常。
-
专门把参数检查做成一个函数,满足代码复用、简洁的原则。
抛出异常时指明具体异常,避免笼统的Exception。public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } public static void sort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); }
-
对数组升序排序,此处使用了java.util.DualPivotQuicksort双枢轴快速排序算法,算法复杂度O(nlogn),比传统的单枢轴快排更快。
-
提供int、long、short、char、byte、float、double数组的排序。
//672 line
public static void parallelSort(int[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0);
else
new ArraysParallelSortHelpers.FJInt.Sorter
(null, a, new int[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
- 平行排序算法:当数组长度小于最小粒度(MIN_ARRAY_SORT_GRAN)时,直接用双枢轴快排。反之将数组划分成小于最小粒度的子数组排序,最后再合并排序,此处利用了分治法实现并行排序。
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++];
}
}
private static void swap(Object[] x, int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}
- 旧版的合并排序,基于该排序的算法将被删除了。
public static int binarySearch(char[] a, int fromIndex, int toIndex,
char key) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key);
}
// Like public version, but without range checks.
private static int binarySearch0(char[] a, int fromIndex, int toIndex,
char key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
char 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 boolean equals(long[] a, long[] a2) {
if (a==a2)//同一个数组相等
return true;
if (a==null || a2==null)//null不等
return false;
int length = a.length;
if (a2.length != length) //长度不等,则不同
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i]) //相同位置元素有不同则不等
return false;
return true; //否则相等
}
- 判断两个数组是否相等
public static void fill(long[] a, long val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
- 数组填充:用值val填充数组a,复杂度O(n)
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
- 复制数组:将原始数组复制newLength个元素,使用了 System.arraycopy()的方法,返回新数组。
- System.arraycopy(原始数组, 原始起始索引, 原始终止位置(终止索引+1), 目标数组起始索引,目标数组终止位置(终止索引+1));
3440 line……