2017-06-14 58 views
-4

雖然我使用下面的比較器對一個對象進行排序,但我得到的比較方法違反了它在比較器中的一般合同問題。Java 8比較方法違反了它在比較器中的一般合同問題

final Set<Span> set = new TreeSet<Span>(new Comparator<Span>() { 

     public int compare(final Span firstSpan, final Span secSpan) { 
      BigInteger s1X0 = firstSpan.getCoordinates().getX0(); 
      BigInteger s1X1 = firstSpan.getCoordinates().getX1(); 
      BigInteger s2X0 = secSpan.getCoordinates().getX0(); 
      BigInteger s2X1 = secSpan.getCoordinates().getX1(); 

      BigInteger s1Y0 = firstSpan.getCoordinates().getY0(); 
      final BigInteger s2Y0 = secSpan.getCoordinates().getY0(); 

      if(s1X0.intValue() == s2X0.intValue() && s1X1.intValue() == s2X1.intValue() && s1Y0.intValue() == s2Y0.intValue()){ 
       return 0; 
      } 
      if ((s1Y0.intValue() - s2Y0.intValue() <= 5) && (s1Y0.intValue() - s2Y0.intValue() >= -5)) { 
       return (s1X0.intValue()>s2X0.intValue()) ? 1 : -1; 
      } else { 
       if ((s1X0.intValue() >= s2X0.intValue() && s1X0.intValue() <= s2X1.intValue()) 
         || (s2X0.intValue() >= s1X0.intValue() && s2X0.intValue() <= s1X1.intValue())) { 
        return (s1Y0.intValue() > s2Y0.intValue()) ? 1 : -1; 
       } else { 
        return s1X0.intValue() > s2X0.intValue() ? 1 : -1; 
       } 
      } 

     } 

    }); 
+4

鑑於您調用了'intValue()'24次,爲什麼不只是製作's1X0'等'int'變量?這會讓你更容易幫助你,而且你的代碼更易於閱讀。 –

+3

如果你告訴我們你想要達到的目標,並且理想地提供一個展示問題的[mcve],那麼這也會有所幫助 - 舉個具體的例子,我們應該很容易向你展示你的比較不一致的地方。 –

+3

你明白那個錯誤信息的含義嗎?仔細閱讀['java.util.Comparator']的API文檔(http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html),它解釋了實現的要求'比較'方法。您的實施違反了這些要求,因此您必須檢查您的代碼並進行調整以確保其符合要求。 – Jesper

回答

5

一個Comparator必須處以總訂貨就可以比較的對象。特別是這意味着它必須是過渡性的,即,如果a小於b,並且b小於c,則a必須小於c。您的Comparator沒有該屬性。

考慮下面的例子:

a.getX0() == 1 b.getX0() == 2 c.getX0() == 3 
a.getX1() == 4 b.getX1() == 5 c.getX1() == 6 
a.getY0() == 4 b.getY0() == 0 c.getY0() == -4 

則認爲a小於b(在Y0之差小於5),b小於c(所不同的是Y0小於5 ),但a不小於c(y0的差值大於5,因此取y0值)。

這三個對象按什麼順序排序?

此外,您的代碼還有其他問題。如果將所有內容都轉換爲int,則可能會發生溢出(這也可能導致您提到的異常)。當數據存儲爲BigInteger時,您還應該使用BigInteger進行比較,例如使用例如BigInteger。方法BigInteger.subtractBigInteger.compare

1

通過使用BigInteger.intValue,您只是假定所有數字都適合簡單整數。

因爲BigInteger是一個Comparable,所以您應該依賴BigInteger.compare而不是比較int值。

+2

這應該只是一個評論,而不是一個完整的答案。 –

+0

因爲我沒有所需的聲望,所以我不可能評論其他人的答案,... –

相關問題