我有1300个项目的数据,用我的comperator排序。当我使用JAVA 6时,排序工作正常。 当项目在JAVA 7上运行时,我得到了这个例外:
环境:JAVA 7,Vaadin 6.8.12,测试时发生了32位和64位相同的错误。 (它在JAVA 6上工作正常)
Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at com.vaadin.data.util.AbstractInMemoryContainer.doSort(AbstractInMemoryContainer.java:575)
at com.vaadin.data.util.AbstractInMemoryContainer.sortContainer(AbstractInMemoryContainer.java:555)
at com.vaadin.data.util.AbstractBeanContainer.sort(AbstractBeanContainer.java:440)
at com.vaadin.ui.CustomTable.sort(CustomTable.java:4552)
这是我正在使用的兼容者:
private class StudyRecordComparator implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String) {
return ((String) o1).compareToIgnoreCase(((String) o2));
}
else if (o1 instanceof QuestionnaireStatusType && o2 instanceof QuestionnaireStatusType) {
QuestionnaireStatusType status1 = (QuestionnaireStatusType) o1;
QuestionnaireStatusType status2 = (QuestionnaireStatusType) o2;
if(status1.equals(status2)) {
return 0;
}
switch(status1) {
case WAITING_FOR_REVIEW :
return -1;
case IN_REVIEW :
if(status2.equals(QuestionnaireStatusType.WAITING_FOR_REVIEW)) {
return 1;
} else {
return -1;
}
case WAITING_PUBLICATION :
if(status2.equals(QuestionnaireStatusType.WAITING_FOR_REVIEW) || status2.equals(QuestionnaireStatusType.IN_REVIEW)) {
return 1;
} else {
return -1;
}
case PUBLISHED :
if(status2.equals(QuestionnaireStatusType.WITHDRAWN)) {
return -1;
} else {
return 11;
}
case WITHDRAWN :
return 1;
}
}
else if (o1 instanceof Date && o2 instanceof Date) {
return ((Date) o1).compareTo(((Date) o2));
} else if (o1 instanceof Integer && o2 instanceof Integer) {
return ((Integer) o1).compareTo(((Integer) o2));
} else if (o1 instanceof User && o2 instanceof User) {
return ((User)o1).toString().compareToIgnoreCase(((User)o2).toString());
}
return 0;
}
}
public enum QuestionnaireStatusType {
IN_PROGRESS("In progress"),
WAITING_FOR_REVIEW("Waiting for review"),
IN_REVIEW("In review"),
WAITING_PUBLICATION("Waiting for publication"),
PUBLISHED("Published"),
WITHDRAWN("Withdrawn");
private final String field;
public String getField() {
return field;
}
QuestionnaireStatusType(String field){
this.field = field;
}
}
答案 0 :(得分:2)
您的收藏集是否包含null
?
如果是这样,比较器有一个问题:null
总是返回0,因此null
被视为等于一切。
作为A > B
(前提)的结果,您还有A == null
和null == B
,因此传递性A
和B
也应该相等,这违反了前提。
您需要为所有可能的值建立一个完整且一致的排序(如果允许,则包括null
)。
当您的集合包含混合类型(一些字符串,一些日期,一些QuestionnaireStatusType)时,会出现同样的问题。