Java Comparable Class - 比较方法违反了它的一般契约

标签 java

我正在编写一个基于 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.

我假设 xyint .如果他们是 float那么问题的真正原因就更难理解了。无论哪种方式,使用 Float.compare(x, y)是更好的解决方案。

但是如果xy实际上是int , 然后使用 Float.compare(x, y)会给你一些x不正确答案和 y值。对于 x 的接近值和 y具有足够大的幅度,intfloat转换将失去精度,并且 Float.compare会说他们是平等的。

关于Java Comparable Class - 比较方法违反了它的一般契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36110836/

相关文章:

Java list 文件

java - GSON 到 JSON 转换 - 长格式和简单日期格式 "yyyy-MM-dd' T'HH :mm'Z'"

java - 在 Eclipse 中使用 Ant 的类路径

java - 比较两个语句与一个定义变量java

java - NativeScript HelloWorld build.gradle错误

java - 谁能准确解释为什么串行版本 ID 在 Java 中是静态的

java - 在tomcat中运行jsp文件出错?

java - Selendroid 尝试启动 session 时进入无限循环

java - Java 匹配与 JavaScript 匹配之间的结果差异

java - 如何将 PrintStream 绑定(bind)到 System.out 和 err 流