2009-03-03 16 views
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); 
    } 
} 

を。私はその後、Arrays.sortの2つの引数形式を使用し

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

:だから私は、単純なcopmaratorを作成しました。

これは私のテストケースでうまくいきますが、配列が奇妙ではあるが反復可能な順序で終わることが時々間違っています。 これはどのようにすることができますか?

+0

どのように間違っていますか? – MarkusQ

+0

それはパズルです! – erickson

答えて

20

整数オーバーフローとhellip;より正確には、アンダーフロー。代わりに

、明示的な比較を行います。

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); 
    } 
}; 

あなたは差が「ラップアラウンド」ではないと確信している場合は減算を使用して結構です。例えば、問題の値が非負であると制約されている場合。

15

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

代わりに、このアルゴリズムを使用します。

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

私はそのような目的のためのライブラリにこの機能を持っているのが好き。

+0

しばらくの間、Integerの静的メソッドを紹介します。しかし、そこにはありません... –

+1

@Tom: 'Integer.valueOf(x).compareTo(y);'は私が考えることができる最も簡潔な方法です。 Doubleが静的な 'compare()'メソッドを持ち、他の数値タイプはそうではないことを妙に思います。 – Grundlefleck

+2

@Grundlefleck:True!しかし、私のメソッドは、新しい 'Integer'インスタンスを作成しないので、実行する方がはるかに高速です。 –

2

あなたはそこにどのような数字を投げますか?あなたの数値が十分に大きければ、整数のMIN/MAX値を折り返して混乱させることになります。

1

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

IIRCは、のIntオーバーフローが黙っJVM

にラップアラウンド - MarkusQ

5

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

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

を試してみてください

+0

+1は、最も明白でない「ラッピング」失敗のケースです。 –

4

Javaプリミティブを比較する場合は、それらをオブジェクトの対応するオブジェクトに変換して、compareTo()メソッドに依存することをお勧めします。あなたが行うことができます。この場合

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

疑いで、十分にテストされたライブラリを使用しています。

+3

オーバーヘッドのビット(小数でない値の場合)。 –

関連する問題