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が大部分で私を打ち負かしましたが、詳しく説明し、おそらく明確にするために...

Compare メソッドは、かなり「安定」しており、完全でなければなりません。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 の 2 つのポイントがあるとします。

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 に答える