2013-11-26 106 views
1

我试图整理保存字符串和一个双值对象的列表:Collections.sort抛出:IllegalArgumentException -

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将字符串列表转换为字符串,添加了锁代码并评论我正试图使其工作的行。 另外我应该提到的例外只发生在有时,但我没有使用线程。

+1

http://stackoverflow.com/questions/11441666/java-error-comparison-method-violates-its-general-contract – Areo

+0

if(ans == 0)return Integer.compare(x.hashCode(),y .hashCode());看起来真的怀疑在这里。 – tjg184

+1

'utils.listToString(...)。compareTo(...)'这行是干什么的?其结果未被使用。你在引用整个代码吗?这条线是否正确? –

回答

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

谢谢你,但它,没有帮助 – user1120007

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的默认实现(返回对象的整数表示内部地址)你是说当两个对象在内存中是同一个对象时,它们将被视为相等。

+0

我建议的压缩机没有与相同的异常工作后,我添加了hashCode。 另外我有一种情况,如果两个对象有相同的文本,我不想排序运行其中之一。 – user1120007

+0

为什么你会期望排序不会因为你使用散列码而在其中一个对象上运行? – bcorso

+0

由于看起来没有两个对象,但它们可以具有相同的文本。 – user1120007

相关问题