深入學習java原始碼之 Arrays.sort()與Arrays.parallelPrefix()
深入學習java原始碼之 Arrays.sort()與Arrays.parallelPrefix()
Comparator介面
能對不同型別的物件進行排序(當然排序依據還是基本型別),也不用自己實現排序演算法,用起來很方便。
對任意型別集合物件進行整體排序,排序時將此介面的實現傳遞給Collections.sort方法或者Arrays.sort方法排序。
實現int compare(T o1, T o2);
方法,返回正數,零,負數各代表大於,等於,小於。
public class Test { private final class CompareName implements Comparator<Milan> { boolean is_Ascend; public CompareName(boolean b) { // TODO Auto-generated constructor stub is_Ascend = b; } @Override public int compare(Milan o1, Milan o2) { // TODO Auto-generated method stub if (is_Ascend) return o1.p_Name.compareTo(o2.p_Name); else return o2.p_Name.compareTo(o1.p_Name); } } private final class CompareId implements Comparator<Milan> { boolean is_Ascend; public CompareId(boolean b) { // TODO Auto-generated constructor stub is_Ascend = b; } @Override public int compare(Milan o1, Milan o2) { // TODO Auto-generated method stub int a, b; if (is_Ascend) { a = o1.p_Id; b = o2.p_Id; } else { a = o2.p_Id; b = o1.p_Id; } if (a > b) return 1; else if (a == b) return 0; else return -1; } } public static void main(String[] args) { Test t = new Test(); Milan p1 = new Milan(1, "Dida"); Milan p2 = new Milan(2, "Cafu"); Milan p3 = new Milan(3, "Maldini"); Milan P4 = new Milan(6, "Baresi"); Milan p5 = new Milan(9, "Inzaghi"); Milan P6 = new Milan(10, "Costa"); List<Milan> mList = new ArrayList<Milan>(); mList.add(p1); mList.add(P6); mList.add(P4); mList.add(p2); mList.add(p5); mList.add(p3); System.out.println("初始順序"); System.out.println("姓名 | 號碼"); for (Milan p : mList) { System.out.println(p.p_Name + " | " + p.p_Id); } System.out.println(); System.out.println("對號碼降序"); System.out.println("姓名 | 號碼"); Collections.sort(mList, t.new CompareId(false)); for (Milan p : mList) { System.out.println(p.p_Name + " | " + p.p_Id); } System.out.println(); System.out.println("對姓名升序"); System.out.println("姓名 | 號碼"); Collections.sort(mList, t.new CompareName(true)); for (Milan p : mList) { System.out.println(p.p_Name + " | " + p.p_Id); } } }
Comparator<? super E> c
構造器需要一個Comparator類來比較兩個元素,以E為String類時為例,此時的Comparator可以是Comparator<String>,也可以是Comparator<Object>,但Comparator<Integer>就不行,這樣就保證了傳給構造器的Comparator是可以進行E元素的比較的。
public static <T> void sort(T[] a, Comparator<? super T> c) { } --------------------- import java.util.Comparator; public class StringCompartor implements Comparator<String> { //用來封裝一個排序規則的方法 // static <T> void // sort(T[] a, Comparator<? super T> c); // 根據指定比較器產生的順序對指定物件陣列進行排序 @Override public int compare(String arg0, String arg1) {//接收兩個引數 // TODO Auto-generated method stub // compareTo(String anotherString) // 按字典順序比較兩個字串。 return arg0.compareTo(arg1);//返回一個排序規則 } --------------------- String demos[] = { "hello", "New", "test", "CSDN" }; // // static <T> void // sort(T[] a, Comparator<? super T> c) // 根據指定比較器產生的順序對指定物件陣列進行排序。 Arrays.sort(demos, new StringCompartor()); //呼叫已經封裝好的排序規則進行排序 ,符合面向物件的程式設計思想 for(String demo:demos){ System.out.println(demo); } ---------------------
java.util.Collections的max方法用於獲得一個容器中的最大值,這個函式頭可以這樣寫:
public static <T extends Comparable<T>> T max(Collection<T> coll)
這樣就限定T為能和自己比較的類,過於嚴格
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) { Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while(i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
Modifier and Type | Method and Description |
---|---|
static void |
parallelPrefix(double[] array, DoubleBinaryOperator op) 使用提供的功能,並行地計算給定陣列的每個元素。 |
static void |
parallelPrefix(double[] array, int fromIndex, int toIndex, DoubleBinaryOperator op) 對於陣列的給定子範圍執行 |
static void |
parallelPrefix(int[] array, IntBinaryOperator op) 使用提供的功能,並行地計算給定陣列的每個元素。 |
static void |
parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op) 對於陣列的給定子範圍執行 |
static void |
parallelPrefix(long[] array, int fromIndex, int toIndex, LongBinaryOperator op) 對於陣列的給定子範圍執行 |
static void |
parallelPrefix(long[] array, LongBinaryOperator op) 使用提供的功能,並行地計算給定陣列的每個元素。 |
static <T> void |
parallelPrefix(T[] array, BinaryOperator<T> op) 使用提供的功能,並行地計算給定陣列的每個元素。 |
static <T> void |
parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator<T> op) 對於陣列的給定子範圍執行 |
static void |
parallelSetAll(double[] array, IntToDoubleFunction generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
parallelSetAll(int[] array, IntUnaryOperator generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
parallelSetAll(long[] array, IntToLongFunction generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static <T> void |
parallelSetAll(T[] array, IntFunction<? extends T> generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
parallelSort(byte[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(byte[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(char[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(char[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(double[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(double[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(float[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(float[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(int[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(int[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(long[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(long[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static void |
parallelSort(short[] a) 按照數字順序排列指定的陣列。 |
static void |
parallelSort(short[] a, int fromIndex, int toIndex) 按照數字順序排列陣列的指定範圍。 |
static <T extends Comparable<? super T>> |
parallelSort(T[] a) 對指定物件升序排列的陣列,根據natural ordering的元素。 |
static <T> void |
parallelSort(T[] a, Comparator<? super T> cmp) 根據指定的比較器引發的順序對指定的物件陣列進行排序。 |
static <T extends Comparable<? super T>> |
parallelSort(T[] a, int fromIndex, int toIndex) 對指定物件升序排列的陣列的指定範圍內,根據natural ordering的元素。 |
static <T> void |
parallelSort(T[] a, int fromIndex, int toIndex, Comparator<? super T> cmp) 根據指定的比較器引發的順序對指定的物件陣列的指定範圍進行排序。 |
static void |
sort(byte[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(byte[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(char[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(char[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(double[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(double[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(float[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(float[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(int[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(int[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(long[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(long[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static void |
sort(Object[] a) 對指定物件升序排列的陣列,根據natural ordering的元素。 |
static void |
sort(Object[] a, int fromIndex, int toIndex) 對指定物件升序排列的陣列的指定範圍內,根據natural ordering的元素。 |
static void |
sort(short[] a) 按照數字順序排列指定的陣列。 |
static void |
sort(short[] a, int fromIndex, int toIndex) 按升序排列陣列的指定範圍。 |
static <T> void |
sort(T[] a, Comparator<? super T> c) 根據指定的比較器引發的順序對指定的物件陣列進行排序。 |
static <T> void |
sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) 根據指定的比較器引發的順序對指定的物件陣列的指定範圍進行排序。 |
java原始碼
package java.util;
import java.lang.reflect.Array;
import java.util.concurrent.ForkJoinPool;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.DoubleBinaryOperator;
import java.util.function.IntBinaryOperator;
import java.util.function.IntFunction;
import java.util.function.IntToDoubleFunction;
import java.util.function.IntToLongFunction;
import java.util.function.IntUnaryOperator;
import java.util.function.LongBinaryOperator;
import java.util.function.UnaryOperator;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Arrays {
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}
static final class NaturalOrder implements Comparator<Object> {
@SuppressWarnings("unchecked")
public int compare(Object first, Object second) {
return ((Comparable<Object>)first).compareTo(second);
}
static final NaturalOrder INSTANCE = new NaturalOrder();
}
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);
}
}
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);
}
public static void sort(long[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
public static void sort(long[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}
public static void sort(short[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
public static void sort(short[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}
public static void sort(char[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
public static void sort(char[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}
public static void sort(byte[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1);
}
public static void sort(byte[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
}
public static void sort(float[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
public static void sort(float[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}
public static void sort(double[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
public static void sort(double[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}
public static void parallelSort(byte[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
DualPivotQuicksort.sort(a, 0, n - 1);
else
new ArraysParallelSortHelpers.FJByte.Sorter
(null, a, new byte[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(byte[] 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);
else
new ArraysParallelSortHelpers.FJByte.Sorter
(null, a, new byte[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(char[] 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.FJChar.Sorter
(null, a, new char[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(char[] 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);
else
new ArraysParallelSortHelpers.FJChar.Sorter
(null, a, new char[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(short[] 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.FJShort.Sorter
(null, a, new short[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(short[] 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);
else
new ArraysParallelSortHelpers.FJShort.Sorter
(null, a, new short[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
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();
}
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);
else
new 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();
}
public static void parallelSort(long[] 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.FJLong.Sorter
(null, a, new long[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(long[] 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);
else
new ArraysParallelSortHelpers.FJLong.Sorter
(null, a, new long[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(float[] 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.FJFloat.Sorter
(null, a, new float[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(float[] 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);
else
new ArraysParallelSortHelpers.FJFloat.Sorter
(null, a, new float[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(double[] 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.FJDouble.Sorter
(null, a, new double[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
public static void parallelSort(double[] 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);
else
new ArraysParallelSortHelpers.FJDouble.Sorter
(null, a, new double[n], fromIndex, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void parallelSort(T[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, 0, n, NaturalOrder.INSTANCE, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<T>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, NaturalOrder.INSTANCE).invoke();
}
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>>
void parallelSort(T[] 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)
TimSort.sort(a, fromIndex, toIndex, NaturalOrder.INSTANCE, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<T>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
fromIndex, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, NaturalOrder.INSTANCE).invoke();
}
@SuppressWarnings("unchecked")
public static <T> void parallelSort(T[] a, Comparator<? super T> cmp) {
if (cmp == null)
cmp = NaturalOrder.INSTANCE;
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, 0, n, cmp, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<T>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, cmp).invoke();
}
@SuppressWarnings("unchecked")
public static <T> void parallelSort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> cmp) {
rangeCheck(a.length, fromIndex, toIndex);
if (cmp == null)
cmp = NaturalOrder.INSTANCE;
int n = toIndex - fromIndex, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, fromIndex, toIndex, cmp, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<T>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
fromIndex, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, cmp).invoke();
}
static final class LegacyMergeSort {
private static final boolean userRequested =
java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"java.util.Arrays.useLegacyMergeSort")).booleanValue();
}
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
/** To be removed in a future release. */
private static void legacyMergeSort(Object[] a) {
Object[] aux = a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
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);
}
/** To be removed in a future release. */
private static void legacyMergeSort(Object[] a,
int fromIndex, int toIndex) {
Object[] aux = copyOfRange(a, fromIndex, toIndex);
mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
}
private static final int INSERTIONSORT_THRESHOLD = 7;
@SuppressWarnings({"unchecked", "rawtypes"})
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 <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
/** To be removed in a future release. */
private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
T[] aux = a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0);
else
mergeSort(aux, a, 0, a.length, 0, c);
}
public static <T> void sort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
if (c == null) {
sort(a, fromIndex, toIndex);
} else {
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex, c);
else
TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);
}
}
/** To be removed in a future release. */
private static <T> void legacyMergeSort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
T[] aux = copyOfRange(a, fromIndex, toIndex);
if (c==null)
mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
else
mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c);
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static void mergeSort(Object[] src,
Object[] dest,
int low, int high, int off,
Comparator c) {
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 && c.compare(dest[j-1], 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, c);
mergeSort(dest, src, mid, high, -off, c);
// 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 (c.compare(src[mid-1], 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 && c.compare(src[p], src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
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();
}
public static <T> void parallelPrefix(T[] array, int fromIndex,
int toIndex, BinaryOperator<T> op) {
Objects.requireNonNull(op);
rangeCheck(array.length, fromIndex, toIndex);
if (fromIndex < toIndex)
new ArrayPrefixHelpers.CumulateTask<>
(null, op, array, fromIndex, toIndex).invoke();
}
public static void parallelPrefix(long[] array, LongBinaryOperator op) {
Objects.requireNonNull(op);
if (array.length > 0)
new ArrayPrefixHelpers.LongCumulateTask
(null, op, array, 0, array.length).invoke();
}
public static void parallelPrefix(long[] array, int fromIndex,
int toIndex, LongBinaryOperator op) {
Objects.requireNonNull(op);
rangeCheck(array.length, fromIndex, toIndex);
if (fromIndex < toIndex)
new ArrayPrefixHelpers.LongCumulateTask
(null, op, array, fromIndex, toIndex).invoke();
}
public static void parallelPrefix(double[] array, DoubleBinaryOperator op) {
Objects.requireNonNull(op);
if (array.length > 0)
new ArrayPrefixHelpers.DoubleCumulateTask
(null, op, array, 0, array.length).invoke();
}
public static void parallelPrefix(double[] array, int fromIndex,
int toIndex, DoubleBinaryOperator op) {
Objects.requireNonNull(op);
rangeCheck(array.length, fromIndex, toIndex);
if (fromIndex < toIndex)
new ArrayPrefixHelpers.DoubleCumulateTask
(null, op, array, fromIndex, toIndex).invoke();
}
public static void parallelPrefix(int[] array, IntBinaryOperator op) {
Objects.requireNonNull(op);
if (array.length > 0)
new ArrayPrefixHelpers.IntCumulateTask
(null, op, array, 0, array.length).invoke();
}
public static void parallelPrefix(int[] array, int fromIndex,
int toIndex, IntBinaryOperator op) {
Objects.requireNonNull(op);
rangeCheck(array.length, fromIndex, toIndex);
if (fromIndex < toIndex)
new ArrayPrefixHelpers.IntCumulateTask
(null, op, array, fromIndex, toIndex).invoke();
}
}