Java 集合排序:排序列表时出现问题
Java Collection Sort: Issue while sorting list
这个问题已经被问过很多次,我的理解是 return 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;
}
});
也和JDK的版本有关。如果在JDK6做的不错,可能会出现你描述的JDK7中的问题,因为jdk7中的实现方法已经改变了。
看看这个:
说明:java.util.Arrays.sort 和 java.util.Collections.sort(间接)使用的排序算法已被替换。如果新的排序实现检测到违反 Comparable 协定的 Comparable,它可能会抛出 IllegalArgumentException。之前的实现默默忽略了这样的情况。如果需要以前的行为,您可以使用新系统 属性、java.util.Arrays.useLegacyMergeSort 来恢复以前的合并排序行为。
我不知道具体原因。但是,如果您在使用排序之前添加代码。会好的。
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
我尝试清理您的代码并向其中添加一些我自己的见解。看到您使用 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();
}
}
});
这个问题已经被问过很多次,我的理解是 return 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;
}
});
也和JDK的版本有关。如果在JDK6做的不错,可能会出现你描述的JDK7中的问题,因为jdk7中的实现方法已经改变了。
看看这个:
说明:java.util.Arrays.sort 和 java.util.Collections.sort(间接)使用的排序算法已被替换。如果新的排序实现检测到违反 Comparable 协定的 Comparable,它可能会抛出 IllegalArgumentException。之前的实现默默忽略了这样的情况。如果需要以前的行为,您可以使用新系统 属性、java.util.Arrays.useLegacyMergeSort 来恢复以前的合并排序行为。
我不知道具体原因。但是,如果您在使用排序之前添加代码。会好的。
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
我尝试清理您的代码并向其中添加一些我自己的见解。看到您使用 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();
}
}
});