2013-11-26 141 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

相關問題