我正在尝试对包含字符串和双精度值的对象列表进行排序:
lock.tryLock();
if (testTagRev.size() > 0)
Collections.sort(testTagRev, documentSampleComperator);
lock.unlock();
documentSampleComperator是一个类型documentSampleComparer:
class documentSampleComparer implements Comparator<DocumentSample> {
@Override
public int compare(DocumentSample x, DocumentSample y) {
int ans = x.getText().toString().compareTo(y.getText().toString());
// ans = utils.listToString(x.getText(), ' ').compareTo(utils.listToString(y.getText(),' ')); also didn't work
if (ans == 0)
return Integer.compare(x.hashCode(), y.hashCode());
else return ans;
}
}
即使压缩机是传递性的,我仍然会遇到这种情况:
Exception in thread "main" 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 Trainer.MCobjectStream.<init>(MCobjectStream.java:64)
at Trainer.filterRev.<init>(filterRev.java:64)
at Trainer.Train.main(Train.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我正在使用jdk 1.7.0_45,你能看出问题出在哪里吗?
编辑:utils.listToString将字符串列表转换为字符串,添加锁定代码并注释我之前尝试使其生效的行。 另外我应该提一下,有时只会发生例外,但是我没有使用线程。
答案 0 :(得分:1)
实施Comparator
不应涉及对象的hashCode
。通常,您只需compare
按重要性排序每个属性。在您的示例中,如果文本是您想要比较的唯一内容,那么它应该只是:
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
return x.getText().toString().compareTo(y.getText().toString());
}
});
通过比较hashCode的默认实现(返回对象内部地址的整数表示),你会说当两个对象在内存中是同一个对象时,它们将被视为相等。
答案 1 :(得分:0)
尝试使用内部类(在方法比较中没有那么奇怪的2.line)。
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
int ans = x.getText().toString().compareTo(y.getText().toString());
if (ans == 0) {
return Integer.compare(x.hashCode(), y.hashCode());
} else {
return ans;
}
}
}
);