Java Collections.sort抛出IllegalArgumentException
我试图对包含字符串和双精度值的对象列表进行排序:Java Collections.sort抛出IllegalArgumentException,java,sorting,collections,illegalargumentexception,Java,Sorting,Collections,Illegalargumentexception,我试图对包含字符串和双精度值的对象列表进行排序: lock.tryLock(); if (testTagRev.size() > 0) Collections.sort(testTagRev, documentSampleComperator); lock.unlock(); documentSampleComperator是documentSampleComparer类型: class documentSampleComparer implements Comparator&l
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;
}
}
类documentSampleComparer实现Comparator{
@凌驾
公共整数比较(DocumentSample x、DocumentSample y){
int ans=x.getText().toString().compareTo(y.getText().toString());
//ans=utils.listToString(x.getText(),'').compareTo(utils.listToString(y.getText(),'');也不起作用
如果(ans==0)
返回整数.compare(x.hashCode(),y.hashCode());
否则返回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)
线程“main”java.lang.IllegalArgumentException中的异常:比较方法违反了它的一般约定!
位于java.util.TimSort.mergeLo(TimSort.java:747)
位于java.util.TimSort.mergeAt(TimSort.java:483)
位于java.util.TimSort.mergeCollapse(TimSort.java:410)
位于java.util.TimSort.sort(TimSort.java:214)
位于java.util.TimSort.sort(TimSort.java:173)
位于java.util.Arrays.sort(Arrays.java:659)
位于java.util.Collections.sort(Collections.java:217)
在Trainer.MCobjectStream.(MCobjectStream.java:64)
在Trainer.filterRev.(filterRev.java:64)
at Trainer.Train.main(Train.java:56)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我使用的是JDK1.7.045,你能看到问题出在哪里吗
编辑:utils.listToString将字符串列表转换为字符串,添加锁码并注释我之前试图使其工作的行。
另外,我应该提到,异常只是偶尔发生,但是我没有使用线程。尝试使用内部类(在方法比较中没有wierd 2.line)
Collections.sort(目录,新比较器(){
@凌驾
公共整数比较(DocumentSample x、DocumentSample y){
int ans=x.getText().toString().compareTo(y.getText().toString());
如果(ans==0){
返回整数.compare(x.hashCode(),y.hashCode());
}否则{
返回ans;
}
}
}
);
尝试使用内部类(方法比较中没有wierd 2.line)
Collections.sort(目录,新比较器(){
@凌驾
公共整数比较(DocumentSample x、DocumentSample y){
int ans=x.getText().toString().compareTo(y.getText().toString());
如果(ans==0){
返回整数.compare(x.hashCode(),y.hashCode());
}否则{
返回ans;
}
}
}
);
实现比较器
不应涉及对象的hashCode
。通常,您只需按重要性的顺序比较每个属性。在您的示例中,如果文本是唯一要比较的对象,那么它应该是:
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
return x.getText().toString().compareTo(y.getText().toString());
}
});
Collections.sort(目录,新比较器(){
@凌驾
公共整数比较(DocumentSample x、DocumentSample y){
返回x.getText().toString().compareTo(y.getText().toString());
}
});
通过比较hashCode的默认实现(返回对象内部地址的整数表示),您可以说两个对象当且仅当它们是内存中的同一对象时才被视为相等。实现
Comparator
不应涉及对象的hashCode
。通常,您只需按重要性的顺序比较每个属性。在您的示例中,如果文本是唯一要比较的对象,那么它应该是:
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
return x.getText().toString().compareTo(y.getText().toString());
}
});
Collections.sort(目录,新比较器(){
@凌驾
公共整数比较(DocumentSample x、DocumentSample y){
返回x.getText().toString().compareTo(y.getText().toString());
}
});
通过比较hashCode的默认实现(返回对象内部地址的整数表示),您可以说两个对象当且仅当它们是内存中的同一对象时才被视为相等。if(ans==0)返回整数。compare(x.hashCode(),y.hashCode());这里看起来很可疑。行
utils.listToString(…).compareTo(…)
的作用是什么?其结果未被使用。你引用了全部代码吗?这行对吗?我认为“ans”应该是-1,0,+1。也许这就是问题所在?因为比较器似乎没有违反传递性,我怀疑比较的属性(要么getText().toString()
要么hashCode()
要么两者)在执行过程中发生了变化。如果(ans==0)返回整数。比较(x.hashCode(),y.hashCode());这里看起来很可疑。行utils.listToString(…).compareTo(…)
的作用是什么?其结果未被使用。你引用了全部代码吗?这行对吗?我认为“ans”应该是-1,0,+1。也许这就是问题所在?因为比较器似乎没有违反传递性,所以我怀疑比较的属性(要么getText().toString()
要么hashCode()
要么两者)在执行过程中发生了变化。我在建议的压缩程序无法工作后添加了hashCode,但出现了相同的异常。还有一种情况是,如果两个对象具有相同的文本,我不希望sort在其中一个对象上运行。为什么仅仅因为使用hashcode,就希望sort不会在其中一个对象上运行?因为没有两个对象是相同的,但它们可以具有相同的文本。如果两个对象具有相同的文本,则代码仍会对它们进行排序。它只是根据它们在内存中的随机地址对它们进行排序。所以仍然不确定为什么你们认为sort“不会运行”