【问题标题】:Java Comparable Object Sorting: compareTo(Object) errorJava 可比较对象排序:compareTo(Object) 错误
【发布时间】:2013-08-01 21:19:14
【问题描述】:

我有这个 compareTo 函数,它会继续(但并非总是)抛出关于其一般合同的错误,如果您通过 Comparable 类进行了排序,则可能在某个时候遇到了错误。

public int compareTo(FollowableEntity otherEntity) {
    if(followTarget == null || otherEntity == null || otherEntity.followTarget == null || !otherEntity.follows) return 0;
    if(this.followTarget != otherEntity.followTarget) return 0;
    if(this.getDistanceSqToEntity(followTarget) == otherEntity.getDistanceToEntity(followTarget) && this.getDistanceSqToEntity(otherEntity) < this.getDistanceSqToEntity(followTarget)) return 1;
    if(this.getDistanceSqToEntity(followTarget) == otherEntity.getDistanceToEntity(followTarget) && this.getDistanceSqToEntity(otherEntity) > this.getDistanceSqToEntity(followTarget)) return -1;
    if(this.getDistanceSqToEntity(followTarget) < otherEntity.getDistanceSqToEntity(followTarget) && (this.getDistanceSqToEntity(followTarget) < this.getDistanceSqToEntity(otherEntity))) return -1;
    if(this.getDistanceSqToEntity(followTarget) < otherEntity.getDistanceSqToEntity(followTarget) && (this.getDistanceSqToEntity(followTarget) > this.getDistanceSqToEntity(otherEntity))) return 1;
    if(this.getDistanceSqToEntity(followTarget) > otherEntity.getDistanceSqToEntity(followTarget)) return 1;

    return 0;

}


FollowableEntity has double position values: posX, posY, posZ.
(FollowableEntity(obj)).getDistanceSqToEntity(FollowableEntity) returns the squared distance between the entities as a double. (x1 - x)^2 + (y1 - y)^2 + (z1 - z)^2.

从逻辑上讲,前两个条件在比较时不应该发生,但我还是把它们放在那里。

我不确定是什么条件导致错误被抛出,因为唯一的情况是,碰巧有几十个实体围绕彼此旋转以达到目标。

这是日志的一部分,我的日志工具效率很低。

17:23:37 - Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract!
17:23:37 -  at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:714)
17:23:37 -  at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:451)
17:23:37 -  at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376)
17:23:37 -  at java.util.ComparableTimSort.sort(ComparableTimSort.java:182)
17:23:37 -  at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
17:23:37 -  at java.util.Arrays.sort(Arrays.java:472)
17:23:37 -  at java.util.Collections.sort(Collections.java:155)

之后它指向调用 Collections.sort() 的行,但没有告诉我有关 compareTo 函数的任何信息。

【问题讨论】:

  • 如果您发布正在抛出的错误,这将非常有用。
  • 如果您尝试实现Comparable,请注意签名是泛型的,因此在运行时任何类的对象都可以传递给您的compareTo 方法。此外,Comparable 的合同特别指出compareTo(null) 应该抛出NullPointerException,而不是返回“这些是相等的”(0)。
  • 像这样:if(followTarget == null || otherEntity == null || otherEntity.followTarget == null || !otherEntity.follows) throw new NullPointerException(); if(this.followTarget != otherEntity.followTarget) throw new InputMismatchException(); 我的代码功能似乎无法正常工作
  • 您是否考虑过 == 与双打比较会失败? o1.distance(o2) == o2.distance(o1) 可能不是真的。
  • 我在整个系统中发现了一个缺陷,用不同的排序方法从头开始重写它可能会更好。

标签: java sorting logic comparable compareto


【解决方案1】:

我前段时间遇到了与Comparable的合同违约,这与返回矛盾的结果有关;在某些情况下,您的方法可能会为 object1.compareTo(object2)object2.compareTo(object1) 返回 1(或 -1)

你可以在这里找到类似的问题。-

why does my compare method throw exception -- Comparison method violates its general contract!

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 2020-01-11
    • 2016-01-05
    相关资源
    最近更新 更多