2014-06-16 50 views
-3

我試圖排序的集合,收到以下異常:的java的compareTo比較法違反其總承包

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
    at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835) 
    at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453) 
    at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376) 
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:182) 
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:146) 
    at java.util.Arrays.sort(Arrays.java:472) 
    at java.util.Collections.sort(Collections.java:155) 

我知道了3個合同的compareTo的:

  • X .compareTo(y)> 0 & & y.compareTo(z)> 0)表示x.compareTo(z)> 0
  • sgn(x.compareTo(y))== -sgn(y.compareTo(x) )
  • x.compareTo(y)== 0意味着sgn(x.compareTo(z))== sgn(y.compareTo(z))

代碼如下。我可以看到Long.intValue()有可能被截斷,但據我所知,這不應該違反合約。

public class Bar implements Comparable<Bar>{ 

private static final int LOWER = 1; 
private static final int HIGHER = -1; 
private boolean isNoPriority; 
private int priority; 
private String tradeId; 
private long tradeVersion; 



public Bar(boolean isNoPriority, int priority, String tradeId,long tradeVersion) { 
    super(); 
    this.isNoPriority = isNoPriority; 
    this.priority = priority; 
    this.tradeId = tradeId; 
    this.tradeVersion = tradeVersion; 
} 
@Override 
public int compareTo(Bar o) { 

    if (isNoPriority && !o.isNoPriority){    
     return LOWER; 
    } 
    if (!isNoPriority && o.isNoPriority){ 
     return HIGHER; 
    } 

    if (priority == o.priority) { 
     if (tradeId.compareToIgnoreCase(o.tradeId) == 0){     
      return Long.valueOf(tradeVersion).intValue() - Long.valueOf(o.tradeVersion).intValue(); 
     } 
     else { 
      return tradeId.compareToIgnoreCase(o.tradeId);        
     } 
    } 
    else if (priority < o.priority) {    
     return LOWER; 
    } 
    else if (priority > o.priority){     
     return HIGHER;   
    } else { 
     return 0; 
    } 

} 
} 

我不明白什麼是不正確的關於這compareTo實現。

+3

我會添加equals和hashCode。你也需要這些。遵循約書亞布洛赫公約。 – duffymo

+0

@duffymo,添加東西/泡芙/膨脹只是B/C你可以使用它是我的書中的反模式。它本質上是一個關鍵,它不應該用在散列表中。 – bestsss

+0

'返回Long.valueOf(tradeVersion).intValue() - Long.valueOf(o.tradeVersion).intValue();'這是可怕的代碼,也是錯誤的。如果你想比較long值,只需使用'Long.compare(long,long)'。如果你必須在java1.7之前工作。使用一個效用函數:'static int compare(long x,long y){return(x bestsss

回答

相關問題