0

我收到此错误:

Exception in thread "Thread-3" java.lang.IllegalArgumentException: Comparison method violates its general contract!

当我尝试在 Java 中为我的实体系统运行此比较器时:

private Comparator<Entity> spriteSorter = new Comparator<Entity>() {
    public int compare(Entity e0, Entity e1) {
        if (e1.position.getX() <= e0.position.getX())
            return +1;
        if (e1.position.getY() >= e0.position.getY())
            return -1;
        return 0;
    }
};

这是实现:

private void sortAndRender(Bitmap b, Vec2 offset, ArrayList<Entity> l) {
    Collections.sort(l, spriteSorter);
    for (int i = 0; i < l.size(); i++) {
        l.get(i).render(b, offset);
    }
}

当我在屏幕上显示大量实体时,这个问题才真正开始出现。这里发生了什么?

4

3 回答 3

1

您的比较器完全错误。更好的是

    if (e1.position.getX() != e0.position.getX())
        return Integer.compare(e1.position.getX(), e0.position.getX());
    if (e1.position.getY() != e0.position.getY())
        return Integer.compare(e1.position.getY(), e0.position.getY());
    return 0;
于 2013-03-09T17:56:00.490 回答
0

虽然@Louis 在很大程度上击败了我,但要详细说明并可能澄清......

您的比较方法必须相当“稳定”且完整。对于很多 X 和 Y 不同的情况,您的将返回 0,“等于”。

我会将其重写为

int result = Integer.compare(e1.position.getX(), e0.position.getX());
if (result == 0)
  result = Integer.compare(e1.position.getY(), e0.position.getY());
... if you have more to compare, add more if (result == 0) blah blah here...

return result;

至于“稳定”,假设你有两个点,a = 4,2 和 b = 2,4

当你将 a 与 b 比较时,你得到 0 但是当你将 b 与 a 比较时,你得到 1。

这在比较器中是“非法的”。a.compareTo(b) 应该等于 -b.compareTo(a)

于 2013-03-09T18:00:58.513 回答
0

哈哈,问题是我出于某种原因将它们在基于 x 位置的列表中向上移动,并在基于 y 位置的列表中向下移动??!?!?这是我的一个非常愚蠢的错误

于 2013-03-09T18:02:34.953 回答