34

Integer2 つのオブジェクトを比較する必要があります ( ではありませんint)。それらを比較する標準的な方法は何ですか?

Integer x = ...
Integer y = ...

私はこれを考えることができます:

if (x == y) 

演算子は==参照のみを比較するため、これはより低い整数値に対してのみ機能します。しかし、おそらくオートボクシングが作動します...?

if (x.equals(y)) 

これは高価な操作のように見えます。このように計算されたハッシュコードはありますか?

if (x.intValue() == y.intValue())

少し冗長...

編集:ご回答ありがとうございます。今何をすべきかはわかっていますが、事実は既存のすべての回答に分散されており(削除されたものも含めて:))、どれを受け入れるかはよくわかりません。したがって、3 つの比較の可能性すべて、または少なくとも最初の 2 つを参照する最良の回答を受け入れます。

4

9 に答える 9

33

これは equals メソッドが行うことです:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

ご覧のとおり、ハッシュ コードの計算はありませんが、他にもいくつかの操作が行われています。x.intValue() == y.intValue()少し速いかもしれませんが、マイクロ最適化の領域に入ります。さらに、コンパイラはequals()とにかく呼び出しを最適化する可能性がありますが、確かなことはわかりません。

私は通常、プリミティブを使用intしますが、使用する必要がある場合はInteger、 に固執しequals()ます。

于 2009-12-09T15:01:28.753 に答える
26

メソッドを使用しequalsます。高いのになんでそんなに気になるの?

于 2009-12-09T13:21:08.343 に答える
13
if (x.equals(y))

これは高価な操作のように見えます。このように計算されたハッシュコードはありますか?

これは高価な操作ではなく、ハッシュ コードは計算されません。Java は魔法のようにハッシュ コードを計算するのでequals(...)はなく、単なるメソッド呼び出しであり、他のメソッド呼び出しと何ら違いはありません。

JVM はメソッド呼び出しを最適化する (メソッド内で行われる比較をインライン化する) ことさえする可能性が高いため、この呼び出しは==2 つのプリミティブint値で使用するよりもはるかに高価ではありません。

注: マイクロ最適化を時期尚早に適用しないでください。コードはパフォーマンスのボトルネックではないため、「これは遅いに違いない」などの仮定は、おそらく間違っているか、問題ではありません。

于 2009-12-09T13:32:56.730 に答える
9

マイナーな注意: Java 1.7 以降、Integer クラスには静的compare(Integer, Integer)メソッドがあるため、呼び出すだけInteger.compare(x, y)で完了できます (最適化に関する質問は別として)。

もちろん、そのコードは 1.7 より前のバージョンの Java と互換性がないため、x.compareTo(y)代わりに 1.2 と互換性のあるバージョンを使用することをお勧めします。

于 2013-12-12T23:27:22.383 に答える
8

x.equals(y) を使用します。これは、すべてのクラスの等価性を確認する一貫した方法だからです。

パフォーマンスに関する限り、equals は intValue() を呼び出すことになるため、実際にはよりコストがかかります。

編集: ほとんどの場合、オートボクシングを避ける必要があります。特に作者は自分が何をしていたのかを知りません。このコードを試すと、その結果に驚かれることでしょう。

Integer a = 128;
Integer b = 128;

System.out.println(a==b);
于 2009-12-09T13:21:33.117 に答える
2

「等しい」です。安全を期すために、null-nessをテストする必要があります。

x == y || (x != null && x.equals(y))

x==yはnull==nullをテストしますが、これはIMHOが真である必要があります。

コードは、十分な頻度で呼び出されるとJITによってインライン化されるため、パフォーマンスの考慮事項は重要ではありません。

もちろん、可能であれば、プレーンな「int」を優先して「Integer」を回避するのが最善の方法です。

[追加した]

また、等式テストが対称であることを保証するためにnullチェックが必要です。x.equals(y)はy.equals(x)と同じである必要がありますが、いずれかがnullの場合はそうではありません。

于 2009-12-09T13:52:09.677 に答える
1

Integer クラスは を実装Comparable<Integer>しているので、試すことができます。

x.compareTo(y) == 0

また、等しいかどうかではなく、これらの整数を比較しようとしている場合は、

x.compareTo(y) < 0x が y より小さいかどうかを教えてくれます。

x.compareTo(y) > 0x が y より大きいかどうかがわかります。

もちろん、これらの例では、これらの呼び出しを行う前に x が非 null であることを確認するのが賢明です。

于 2009-12-09T18:51:39.190 に答える