`

jdk7中sort内部算法改变

 
阅读更多
在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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics