问题
JDK6升级JDK7的情况下,由于java.util.Arrays.sort和java.util.Collections.sort使用的排序算法已被替换(mergesort → timsort)。当TimSort检测到待比较的项目违反约定,则可能抛出IllegalArgumentException。JDK6及以前的版本忽略了这种情况。如果需要以前的行为,可以使用新的系统属性java.util.Arrays.useLegacyMergeSort来恢复以前的mergesort行为。
/**
*
* @param <T> the class of the objects to be sorted
* @param a the array to be sorted
* @param c the comparator to determine the order of the array. A
* {@code null} value indicates that the elements'
* {@linkplain Comparable natural ordering} should be used.
* @throws ClassCastException if the array contains elements that are
* not <i>mutually comparable</i> using the specified comparator
* @throws IllegalArgumentException (optional) if the comparator is
* found to violate the {@link Comparator} contract
*/
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);
}
}
Collections.sort方法的说明
简单的来说:
- 恒满足
compare(x, y) = - compare(y, x)
,compare(x, y)
抛出异常,compare(y, x)
也必须抛出异常 - 由
(compare(x, y)>0
且compare(y, z)>0)
,可以推导出compare(x, z) > 0
- 由
compare(x, y)==0
,推导出对任意元素z
,恒满足compare(x, z) = compare(y, z)
解决方案
设置JVM启动参数,使用JDK6的默认排序方法。
-Djava.util.Arrays.useLegacyMergeSort=true