--- old/test/jdk/java/util/Arrays/Sorting.java 2018-01-18 06:09:12.226085321 -0800 +++ new/test/jdk/java/util/Arrays/Sorting.java 2018-01-18 06:09:11.850050426 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,20 +24,22 @@ /* * @test * @bug 6880672 6896573 6899694 6976036 7013585 7018258 - * @summary Exercise Arrays.sort * @build Sorting * @run main Sorting -shortrun + * @summary Exercise Arrays.sort * * @author Vladimir Yaroslavskiy * @author Jon Bentley * @author Josh Bloch */ +import java.io.PrintStream; import java.util.Arrays; import java.util.Random; -import java.io.PrintStream; +import java.util.Comparator; public class Sorting { + private static final PrintStream out = System.out; private static final PrintStream err = System.err; @@ -47,7 +49,7 @@ // Array lengths used in a short run private static final int[] SHORT_RUN_LENGTHS = { - 1, 2, 3, 21, 55, 1000, 10000 }; + 1, 2, 3, 21, 55, 1000, 10000, 12000 }; // Random initial values used in a long run (default) private static final long[] LONG_RUN_RANDOMS = { 666, 0xC0FFEE, 999 }; @@ -55,6 +57,10 @@ // Random initial values used in a short run private static final long[] SHORT_RUN_RANDOMS = { 666 }; + // Constant values used in subarray sorting + private static final int A380 = 0xA380; + private static final int B747 = 0xB747; + public static void main(String[] args) { boolean shortRun = args.length > 0 && args[0].equals("-shortrun"); long start = System.currentTimeMillis(); @@ -79,7 +85,7 @@ testEmptyAndNullDoubleArray(); for (int length : lengths) { - testMergeSort(length); + testMergingSort(length); testAndCheckRange(length); testAndCheckSubArray(length); } @@ -283,6 +289,15 @@ checkSorted(a); checkStable(a); out.println(); + + a = build(length, random); + + out.println("Test 'stable' comparator: " + "random = " + random.getSeed() + + ", length = " + length); + Arrays.sort(a, pairComparator); + checkSorted(a); + checkStable(a); + out.println(); } private static void checkSorted(Pair[] a) { @@ -329,6 +344,12 @@ return a; } + private static Comparator pairComparator = new Comparator() { + public int compare(Pair p1, Pair p2) { + return p1.compareTo(p2); + } + }; + private static final class Pair implements Comparable { Pair(int key, int value) { myKey = key; @@ -391,21 +412,21 @@ out.println(); } - private static void testMergeSort(int length) { + private static void testMergingSort(int length) { if (length < 1000) { return; } - ourDescription = "Check merge sorting"; + ourDescription = "Check merging sort"; int[] golden = new int[length]; - int period = 67; // java.util.DualPivotQuicksort.MAX_RUN_COUNT + final int period = 50; for (int m = period - 2; m <= period + 2; m++) { - for (MergeBuilder builder : MergeBuilder.values()) { + for (MergingBuilder builder : MergingBuilder.values()) { builder.build(golden, m); int[] test = golden.clone(); for (TypeConverter converter : TypeConverter.values()) { - out.println("Test 'merge sort': " + converter + " " + + out.println("Test 'merging sort': " + converter + " " + builder + "length = " + length + ", m = " + m); Object convertedGolden = converter.convert(golden); sort(convertedGolden); @@ -469,18 +490,15 @@ private static void testAndCheckFloat(int length, MyRandom random) { ourDescription = "Check float sorting"; float[] golden = new float[length]; - final int MAX = 10; boolean newLine = false; + final int MAX = 12; for (int a = 0; a <= MAX; a++) { for (int g = 0; g <= MAX; g++) { for (int z = 0; z <= MAX; z++) { for (int n = 0; n <= MAX; n++) { for (int p = 0; p <= MAX; p++) { - if (a + g + z + n + p > length) { - continue; - } - if (a + g + z + n + p < length) { + if (a + g + z + n + p != length) { continue; } for (FloatBuilder builder : FloatBuilder.values()) { @@ -544,7 +562,7 @@ private static void prepareSubArray(int[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - a[i] = 0xDEDA; + a[i] = A380; } int middle = (fromIndex + toIndex) >>> 1; int k = 0; @@ -556,7 +574,7 @@ a[i] = k--; } for (int i = toIndex; i < a.length; i++) { - a[i] = 0xBABA; + a[i] = B747; } } @@ -667,7 +685,7 @@ Integer[] b = new Integer[a.length]; for (int i = 0; i < a.length; i++) { - b[i] = new Integer(a[i]); + b[i] = Integer.valueOf(a[i]); } return b; } @@ -675,7 +693,8 @@ abstract Object convert(int[] a); - @Override public String toString() { + @Override + public String toString() { String name = name(); for (int i = name.length(); i < 9; i++) { @@ -828,7 +847,8 @@ abstract void build(int[] a, int m); - @Override public String toString() { + @Override + public String toString() { String name = name(); for (int i = name.length(); i < 12; i++) { @@ -838,7 +858,7 @@ } } - private static enum MergeBuilder { + private static enum MergingBuilder { ASCENDING { void build(int[] a, int m) { int period = a.length / m; @@ -872,11 +892,53 @@ } a[a.length - 1] = 0; } + }, + POINT { + void build(int[] a, int m) { + for (int i = 0; i < a.length; i++) { + a[i] = 0; + } + a[a.length / 2] = m; + } + }, + LINE { + void build(int[] a, int m) { + for (int i = 0; i < a.length; i++) { + a[i] = i; + } + reverse(a, 0, a.length - 1); + } + }, + PEARL { + void build(int[] a, int m) { + for (int i = 0; i < a.length; i++) { + a[i] = i; + } + reverse(a, 0, 2); + } + }, + RING { + void build(int[] a, int m) { + int k1 = a.length / 3; + int k2 = a.length / 3 * 2; + int level = a.length / 3; + + for (int i = 0, k = level; i < k1; i++) { + a[i] = k--; + } + for (int i = k1; i < k2; i++) { + a[i] = 0; + } + for (int i = k2, k = level; i < a.length; i++) { + a[i] = k--; + } + } }; abstract void build(int[] a, int m); - @Override public String toString() { + @Override + public String toString() { String name = name(); for (int i = name.length(); i < 12; i++) { @@ -886,6 +948,14 @@ } } + private static void reverse(int[] a, int lo, int hi) { + for (--hi; lo < hi; ) { + int tmp = a[lo]; + a[lo++] = a[hi]; + a[hi--] = tmp; + } + } + private static enum UnsortedBuilder { RANDOM { void build(int[] a, int m, Random random) { @@ -992,7 +1062,8 @@ abstract void build(int[] a, int m, Random random); - @Override public String toString() { + @Override + public String toString() { String name = name(); for (int i = name.length(); i < 12; i++) { @@ -1039,7 +1110,7 @@ } else if (test instanceof Integer[]) { compare((Integer[]) test, (Integer[]) golden); } else { - failed("Unknow type of array: " + test + " of class " + + failed("Unknown type of array: " + test + " of class " + test.getClass().getName()); } } @@ -1126,7 +1197,7 @@ } else if (object instanceof Integer[]) { checkSorted((Integer[]) object); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } @@ -1222,7 +1293,7 @@ } else if (object instanceof Integer[]) { return checkSumXor((Integer[]) object); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); return -1; } @@ -1318,7 +1389,7 @@ } else if (object instanceof Integer[]) { return checkSumPlus((Integer[]) object); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); return -1; } @@ -1414,7 +1485,7 @@ } else if (object instanceof Integer[]) { sortByInsertionSort((Integer[]) object); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } @@ -1517,7 +1588,7 @@ } else if (object instanceof Integer[]) { Arrays.sort((Integer[]) object); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } @@ -1540,7 +1611,7 @@ } else if (object instanceof Integer[]) { Arrays.sort((Integer[]) object, fromIndex, toIndex); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } @@ -1563,16 +1634,16 @@ } else if (object instanceof Integer[]) { checkSubArray((Integer[]) object, fromIndex, toIndex, m); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } private static void checkSubArray(Integer[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i].intValue() != 0xDEDA) { + if (a[i].intValue() != A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1583,18 +1654,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i].intValue() != 0xBABA) { + if (a[i].intValue() != B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(int[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != 0xDEDA) { + if (a[i] != A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1605,18 +1676,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != 0xBABA) { + if (a[i] != B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(byte[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (byte) 0xDEDA) { + if (a[i] != (byte) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1627,18 +1698,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (byte) 0xBABA) { + if (a[i] != (byte) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(long[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (long) 0xDEDA) { + if (a[i] != (long) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1649,18 +1720,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (long) 0xBABA) { + if (a[i] != (long) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(char[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (char) 0xDEDA) { + if (a[i] != (char) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1671,18 +1742,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (char) 0xBABA) { + if (a[i] != (char) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(short[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (short) 0xDEDA) { + if (a[i] != (short) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1693,18 +1764,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (short) 0xBABA) { + if (a[i] != (short) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(float[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (float) 0xDEDA) { + if (a[i] != (float) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1715,18 +1786,18 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (float) 0xBABA) { + if (a[i] != (float) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } private static void checkSubArray(double[] a, int fromIndex, int toIndex, int m) { for (int i = 0; i < fromIndex; i++) { - if (a[i] != (double) 0xDEDA) { + if (a[i] != (double) A380) { failed("Range sort changes left element on position " + i + - ": " + a[i] + ", must be " + 0xDEDA); + ": " + a[i] + ", must be " + A380); } } @@ -1737,9 +1808,9 @@ } for (int i = toIndex; i < a.length; i++) { - if (a[i] != (double) 0xBABA) { + if (a[i] != (double) B747) { failed("Range sort changes right element on position " + i + - ": " + a[i] + ", must be " + 0xBABA); + ": " + a[i] + ", must be " + B747); } } } @@ -1762,7 +1833,7 @@ } else if (object instanceof Integer[]) { checkRange((Integer[]) object, m); } else { - failed("Unknow type of array: " + object + " of class " + + failed("Unknown type of array: " + object + " of class " + object.getClass().getName()); } } @@ -1771,7 +1842,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1779,14 +1850,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1800,7 +1871,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1808,14 +1879,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1829,7 +1900,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1837,14 +1908,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1858,7 +1929,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1866,14 +1937,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1887,7 +1958,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1895,14 +1966,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1916,7 +1987,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1924,14 +1995,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1945,7 +2016,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1953,14 +2024,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) { @@ -1974,7 +2045,7 @@ try { Arrays.sort(a, m + 1, m); - failed("Sort does not throw IllegalArgumentException " + + failed("Arrays.sort does not throw IllegalArgumentException " + " as expected: fromIndex = " + (m + 1) + " toIndex = " + m); } @@ -1982,14 +2053,14 @@ try { Arrays.sort(a, -m, a.length); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: fromIndex = " + (-m)); } catch (ArrayIndexOutOfBoundsException aoe) { try { Arrays.sort(a, 0, a.length + m); - failed("Sort does not throw ArrayIndexOutOfBoundsException " + + failed("Arrays.sort does not throw ArrayIndexOutOfBoundsException " + " as expected: toIndex = " + (a.length + m)); } catch (ArrayIndexOutOfBoundsException aie) {