java 8
ArrayList.sort() 方法
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
//1、用于并发的计数器
final int expectedModCount = modCount;
//2、用数组的方法,进行排序
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
画重点:
(1)源码中的 elementData 是 new ArrayList()时候创建的
/**DEFAULTCAPACITY_EMPTY_ELEMENTDATA 代码: private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 是个Object 的数组 */
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
ArrayList 的add方法就是不断的相当于在上组上 添加元素
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
(2) Arrays.sort 源码
public static <T> void sort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
if (c == null) {
//1.排序规则为空的时候的默认排序
sort(a, fromIndex, toIndex);
} else {
//2. rangeCheck 方法用作检查数组越界等异常
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
//3.字面理解 剩余归并排序
legacyMergeSort(a, fromIndex, toIndex, c);
else
//4.排序
TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);
}
}
sort() 方法源码解释
public static void sort(Object[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex);
else
ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
}
上面同样是sort 方法,是上面sort 的重写
rangeCheck() 方法, 校验数组规则,由此可见我们使用ArrayList 的时候ArrayIndexOutOfBoundsException 是咋出现的了,(toIndex > arrayLength) 当toIndex(arrayList 的 add 方法会增大) 长度大于 arrayLength (arrayList 对应的数组长度)的时候
/**
* Checks that {@code fromIndex} and {@code toIndex} are in
* the range and throws an exception if they aren't.
*/
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);
}
}
TimSort.sort() 源码
static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
T[] work, int workBase, int workLen) {
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
//1. 数组的剩余个数
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 ,数组是小的(MIN_MERGE 是 32),不进行归并
if (nRemaining < MIN_MERGE) {
//countRunAndMakeAscending 返回 int,解释见 countRunAndMakeAscending 源码
int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
//二分排序
binarySort(a, lo, hi, lo + initRunLen, c);
return;
}
/**
* March over the array once, left to right, finding natural runs,
* extending short natural runs to minRun elements, and merging runs
* to maintain stack invariant.
*/
TimSort<T> ts = new TimSort<>(a, c, work, workBase, workLen);
int minRun = minRunLength(nRemaining);
do {
// Identify next run
int runLen = countRunAndMakeAscending(a, lo, hi, c);
// If run is short, extend to min(minRun, nRemaining)
if (runLen < minRun) {
int force = nRemaining <= minRun ? nRemaining : minRun;
binarySort(a, lo, lo + force, lo + runLen, c);
runLen = force;
}
// Push run onto pending-run stack, and maybe merge
ts.pushRun(lo, runLen);
ts.mergeCollapse();
// Advance to find next run
lo += runLen;
nRemaining -= runLen;
} while (nRemaining != 0);
// Merge all remaining runs to complete sort
assert lo == hi;
ts.mergeForceCollapse();
assert ts.stackSize == 1;
}
countRunAndMakeAscending 方法的源码
private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
Comparator<? super T> c) {
assert lo < hi;
int runHi = lo + 1;
if (runHi == hi)
return 1;
// Find end of run, and reverse range if descending
//小于0 则调整数组的顺序,compare 方法看见了arrayList.sort 方法进行排序的那个规则
if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
//
while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
runHi++;
reverseRange(a, lo, runHi);
} else { // Ascending
while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
runHi++;
}
return runHi - lo;
}
reverseRange 源码
private static void reverseRange(Object[] a, int lo, int hi) {
hi--;
while (lo < hi) {
Object t = a[lo];
a[lo++] = a[hi];
a[hi--] = t;
}
}