我正在编写一个基于 Y 坐标渲染对象的等距游戏,使用可比较的类,按 Y 值排序,Y 值会发生变化。我收到错误消息“比较方法违反了它的一般契约(Contract)!”并阅读了如何返回负数、0 或正数,所以我实现了这个:
public boolean equals(Entity e) {
if ((e.y-y)==0)
return (e.id == id);
return (e.y == y);
}
public int compareTo(Entity e) {
if ((e.y-y)==0)
return (e.id - id);
return (int) (e.y - y); // Render order by y coordinate
}
但我仍然收到错误。如果值发生变化,排序是否会不起作用,或者我做错了什么?
最佳答案
equals
method 不在契约中涉及,所以我们可以忽略它。
我怀疑问题是整数溢出引起的。问题是 x - y
如果 x > y
并不总是给你肯定的答案如果 x < y
则为负数.如果数字之间的差异足够大,则表示 x - y
会溢出,结果会有错误的符号。
如果这是问题所在,那么简单的解决方案就是使用 Integer.compare(x, y)
而不是 x - y
另一种可能性是实体在您(例如)对它们进行排序的同时发生变异。
Float.compare(x, y) has worked much better.
我假设 x
和 y
是int
.如果他们是 float
那么问题的真正原因就更难理解了。无论哪种方式,使用 Float.compare(x, y)
是更好的解决方案。
但是如果x
和 y
实际上是int
, 然后使用 Float.compare(x, y)
会给你一些x
的不正确答案和 y
值。对于 x
的接近值和 y
具有足够大的幅度,int
至 float
转换将失去精度,并且 Float.compare
会说他们是平等的。
关于Java Comparable Class - 比较方法违反了它的一般契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36110836/