在jdk7里sort的算法改变了
以Arrays.sort为例:
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, c);
}
LegacyMergeSort.userRequested这个是系统变量
Boolean b = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("java.util.Arrays.useLegacyMergeSort")).booleanValue();
System.out.println(b);
默认是false,也就是默认为timsort算法。LegacyMergeSort简单的将数组等量二分的方式来递归分组,然后每组用插入排序算法来处理每个分组,然后并归排序。
/**
* Old merge sort implementation can be selected (for
* compatibility with broken comparators) using a system property.
* Cannot be a static boolean in the enclosing class due to
* circular dependencies. To be removed in a future release.
*/
static final class LegacyMergeSort {
private static final boolean userRequested =
java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"java.util.Arrays.useLegacyMergeSort")).booleanValue();
}
注意:
Cannot be a static boolean in the enclosing class due to circular dependencies. To be removed in a future release.
timsort的一些改变有:
1.不采用递归的等数量二分分组
2.内部每个分组采用了二分插入排序
3.谁和谁并归有一套规则。
网上的一些网友发现之前版本的代码在jdk7下异常抛出:
public class ReproJava7Exception {
public static void main(String[] args) {
int[] sample = new int[]
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,1,0,-2,0,0,0,0};
List<Integer> list = new ArrayList<Integer>();
for (int i : sample)
list.add(i);
// use the native TimSort in JDK 7
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// miss the o1 = o2 case on purpose
return o1 > o2 ? 1 : -1;
}
});
}
}
解决方法在实现Comparable接口的时候要1,-1,0都要分出来。
引用:
http://www.lifebackup.cn/timsort-java7.html
http://en.wikipedia.org/wiki/Timsort