Why does this program using Collections.sort only fail for lists of size 32 or more?

后端 未结 2 1580
攒了一身酷
攒了一身酷 2020-12-11 00:48

The following program throws the following exception:

java.lang.IllegalArgumentException: Comparison method violates its general contract!

2条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-11 01:42

    Java 8 uses TimSort algorithm to sort the input. In TimSort there is a merging phase that happens when the length is at least 32. When the length is lower than 32 then a simple sorting algorithm is used that probably doesn't detect the contract violation. Let the source code comments of TimSort.java speak for itself:

    class TimSort {
        /**
         * This is the minimum sized sequence that will be merged.  Shorter
         * sequences will be lengthened by calling binarySort.  If the entire
         * array is less than this length, no merges will be performed.
         *
         * This constant should be a power of two.  It was 64 in Tim Peter's C
         * implementation, but 32 was empirically determined to work better in
         * this implementation.  In the unlikely event that you set this constant
         * to be a number that's not a power of two, you'll need to change the
         * {@link #minRunLength} computation.
         *
         * If you decrease this constant, you must change the stackLen
         * computation in the TimSort constructor, or you risk an
         * ArrayOutOfBounds exception.  See listsort.txt for a discussion
         * of the minimum stack length required as a function of the length
         * of the array being sorted and the minimum merge sequence length.
         */
        private static final int MIN_MERGE = 32;
    

提交回复
热议问题