17

私はこれに単純化したクラスを持っています:

final class Thing {
    private final int value;
    public Thing(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    @Override public String toString() {
        return Integer.toString(value);
    }
}

このことの配列をソートしたいと思います。だから私は簡単なcopmaratorを作成しました:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
        return a.getValue() - b.getValue();
    }
};

次に、の2つの引数形式を使用しますArrays.sort

これは私のテストケースでは問題なく機能しますが、配列が奇妙で繰り返し可能な順序で終わることがあり、すべてがうまくいかないことがあります。どうすればいいの?

4

6 に答える 6

20

整数のオーバーフロー…より正確には、アンダーフロー。

代わりに、明示的な比較を行ってください。

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
      int av = a.getValue(), bv = b.getValue();
      return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
    }
};

差が「ラップアラウンド」しないことが確実な場合は、減算を使用しても問題ありません。たとえば、問題の値が非負になるように制約されている場合です。

于 2009-03-03T23:44:44.610 に答える
15

マイナスを使用して比較を作成することはできません。絶対差がを超えるとオーバーフローしますInteger.MAX_VALUE

代わりに、次のアルゴリズムを使用してください。

int compareInts( int x, int y ) {
  if ( x < y ) return -1;
  if ( x > y ) return 1;
  return 0;
}

私はそのような目的のためにこの関数をライブラリに入れたいと思っています。

于 2009-03-03T23:43:45.907 に答える
5

試す

System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);

これは MAX_VALUE > MIN_VALUE として正の数を返す必要がありますが、代わりに -1 を出力します

于 2009-03-04T07:08:01.940 に答える
5

Java プリミティブを比較するときは、対応するオブジェクトに変換し、そのcompareTo()メソッドに依存することをお勧めします。

この場合、次のことができます。

return Integer.valueOf(a.getValue()).compareTo(b.getValue())

疑わしい場合は、十分にテストされたライブラリを使用してください。

于 2009-03-04T07:59:44.110 に答える
3

そこにどんな数字を入れますか?数値が十分に大きい場合は、整数のMIN / MAX値をラップスルーして、混乱する可能性があります。

于 2009-03-03T23:44:33.130 に答える
2

a の値が非常に負で、b の値が非常に正の場合、答えは非常に間違っています。

IIRC、Int オーバーフローが JVM で静かにラップアラウンドする

-- マーカスQ

于 2009-03-03T23:47:28.037 に答える