【问题标题】:Java Collection Sort: Issue while sorting listJava Collection Sort:排序列表时出现问题
【发布时间】:2015-06-04 15:18:12
【问题描述】:

这个问题已经被问过很多次了,我的理解是它应该返回 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)

代码sn-p

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;
    }
});

【问题讨论】:

  • 当前状态下的代码语法不正确。你有一个悬空的else。请修复您的代码。
  • 您的问题缺少很多细节。 Employee 的什么属性是您比较的基础?在这种情况下,empName 是什么?我们没有看到它在任何地方初始化。什么是员工代码?看起来像一个字符串。代码看起来也很乱。请向我们提供更多详细信息,以便我们为您提供帮助。

标签: java sorting collections


【解决方案1】:

这也与JDK的版本有关。如果在JDK6做的好,可能会出现你说的JDK 7的问题,因为jdk 7的实现方式已经改变了。

看看这个:

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

我不知道确切的原因。但是,如果在使用排序之前添加代码。会好的。

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

【讨论】:

    【解决方案2】:

    我尝试清理您的代码并向其中添加一些我自己的见解。看到您使用 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();
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2021-03-15
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      相关资源
      最近更新 更多