2017-06-14 32 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

因为我没有所需的声望,所以我不可能评论其他人的答案,... –

相关问题