Java Collection排序:排序列表时出现问题

时间:2015-06-04 15:18:12

标签: java sorting collections

这个问题多次被问到我理解的是它应该返回0以及1和-1但是我仍然得到这个例外

java.lang.IllegalArgumentException: Comparison method violates its general contract!  
        at java.util.TimSort.mergeHi(TimSort.java:895)  
        at java.util.TimSort.mergeAt(TimSort.java:512)  
        at java.util.TimSort.mergeForceCollapse(TimSort.java:453)  
        at java.util.TimSort.sort(TimSort.java:250)  
        at java.util.Arrays.sort(Arrays.java:1512)  
        at java.util.ArrayList.sort(ArrayList.java:1454)  
        at java.util.Collections.sort(Collections.java:175)

代码段

Collections.sort(List, new Comparator < Employee > () {
    public int compare(Employee emp1, Employee emp2) {
        int compareVal = 0;
        int returnVal = 0;
        try {
            if (emp1 == emp2) {
                returnVal = 0;
            } else {
                if (empName.equalsIgnoreCase(Constant.EMP_ID)) {
                    if (emp1.getEmpCode() != null && emp2.getEmpCode() != null) {
                        compareVal = emp1.getEmpCode().compareToIgnoreCase(emp2.getEmpCode());
                    }
                } else {
                    compareVal = 5;
                }

                if (compareVal > 0) {
                    returnVal = 1;
                } else if (compareVal < 0) {
                    returnVal = -1;
                } else if (compareVal == 0) {
                    returnVal = 0;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnVal;
    }
});

2 个答案:

答案 0 :(得分:2)

它还与JDK版本有关。如果它在JDK6中运行良好,可能会在您描述的JDK 7中出现问题,因为jdk 7中的实现方法已经改变。

看看这个:

描述:java.util.Arrays.sort和(间接)java.util.Collections.sort使用的排序算法已被替换。如果新的排序实现检测到违反Comparable合同的Comparable,则可能抛出IllegalArgumentException。以前的实现默默地忽略了这种情况。如果需要以前的行为,则可以使用新的系统属性java.util.Arrays.useLegacyMergeSort来恢复先前的mergesort行为。

我不知道确切的原因。但是,如果在使用sort之前添加代码。没关系。

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

答案 1 :(得分:0)

我尝试清理代码并添加一些自己的见解。看到您使用Employee.getEmpCode()作为排序依据,您可能应该emp1.getEmpCode().equals(emp2.getEmpCode())而不是emp1 == emp2。不确定你到底做了什么,但是如果没有局部变量,这就完成了你的功能。

Collections.sort(List, new Comparator < Employee > () {
    public int compare(Employee emp1, Employee emp2) {
        try {
            if (emp1.getEmpCode().equals(emp2.getEmpCode()) {
                return 0;
            } else {
                if (empName.equalsIgnoreCase(Constant.EMP_ID)) {
                    if (emp1.getEmpCode() != null && emp2.getEmpCode() != null) {
                        return emp1.getEmpCode().compareToIgnoreCase(emp2.getEmpCode());
                    }
                } else {
                    return 1;
                }
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});