【发布时间】:2017-11-16 05:10:03
【问题描述】:
当我使用下面的比较器对对象进行排序时,比较方法违反了比较器中的一般合同问题。
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;
}
}
}
});
【问题讨论】:
-
鉴于你调用了
intValue()24 次,你为什么不直接制作s1X0等int变量呢?这样可以更轻松地为您提供帮助,并使您的代码更易于阅读。 -
如果您能告诉我们您想要达到的目标,并且最好提供一个minimal reproducible example 来演示问题,这也会有所帮助 - 给出具体示例,我们应该很容易向您展示您的比较不一致的地方。
-
你明白那个错误信息是什么意思吗?仔细阅读
java.util.Comparator的API 文档,其中解释了compare方法的实现要求。您的实现违反了这些要求,因此您必须检查代码并对其进行调整以确保其符合要求。 -
return s1X0.intValue() > s2X0.intValue() ? 1 : -1;在我看来不是可传递的(如果值相等会发生什么?)。 -
从哪里开始?使用
BigInteger表明值可能超出int范围,否则,您为什么使用BigInteger?因此,仅基于int值进行比较容易出错。您还使用减法而不检查溢出。除此之外,你能用简单的语言解释比较器的逻辑吗?然后,重新检查代码是否真的遵循这个逻辑?
标签: java sorting java-8 comparator