Java での文字型、整数型、および同様の型の比較:等号または == を使用しますか?
質問
Java について確認したいことがありました。Character、Integer、Long などがある場合、equals を使用する必要がありますか、それとも == で十分ですか?
文字列の場合、各一意の文字列のインスタンスが 1 つだけであるという保証がないことはわかっていますが、他のボックス型についてはわかりません。
私の直感では同等のものを使用する必要がありますが、パフォーマンスを無駄にしないようにしたいと考えています。
解決
EDIT:スペックが行うのボクシングの変換のためのいくつかのの保証。 セクション5.1.7 のから:
箱詰めされた値pが真である場合には、 偽、バイト、範囲のchar \ u0000のはu007f、またはintまたはショートを\します -128から127までの数、そしてましょう R1及びR2は、任意の2つの結果であります Pのボクシング変換。いつものこと ケースR1 == R2
実装は、のの大きなプール、あなたの心を使用することができます。
私はの本当にはそのいえに依存しているコードを書いて避けるだろう。ではない、それは失敗する可能性がありますので、それは明らかではないので - 少数の人々は、そのほかの仕様を知っています。 (私は以前、それは実装依存だと思った。)
あなたはequals
を使用するか、または基礎となる値、すなわちを比較する必要があります。
if (foo.equals(bar))
または
if (foo.intValue() == bar.intValue())
オートボクシングが固定値を使用することが保証された場合でも、他の発信者が常にとにかく別々のインスタンスを作成できることに注意してください。
他のヒント
オブジェクトの値について何かを比較したい場合は、次を使用します。 .equals()
.
それらのオブジェクトがプリミティブ ラッパー タイプ Byte、Character、Short、Integer、Long、Float、Double、Boolean である場合でも (特に)。
"==
「オブジェクトのアイデンティティとあなたを比較するだけです。それがあなたが望むものになることは非常にまれです。そして、事実上、プリミティブラッパーでは望むものは決して得られません。
のみ使用します ==
これら 2 つのシナリオのいずれかでは、次のようになります。
- 比較に含まれるすべての値はプリミティブ型です (浮動小数点数ではないことが望ましいです)。
- 2 つの参照が同じオブジェクトを参照しているかどうかを知りたい場合 (これには、
enum
s、値がオブジェクト ID にバインドされているため)
//Quick test
public class Test {
public static void main(String[] args) {
System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
}
}
出力:
"?0それらが等しいです"
答:
いいえ、彼らは同じではないです。あなたは.equalsを使用するか、または彼らのプリミティブ値を比較する必要があります。
箱詰めされた値pが真である場合には、 偽、バイト、範囲のchar \ u0000のはu007f、またはintまたはショートを\します -128から127までの数、そしてましょう R1及びR2は、任意の2つの結果であります Pのボクシング変換。いつものこと ケースR1 == R2
と
ディスカッション
理想的には、プリミティブ所与ボクシング 値pは、常にもたらすであろう 同じ参照。実際には、この 既存の使用可能ではないかもしれません 実装技術。ルール 上記の実用的な妥協案です。ザ・ 最終節は、上記のことを要求します 特定の共通の価値観を常に箱詰めします 区別できないオブジェクトに。ザ・ 実装が遅延し、これらをキャッシュします または熱心ます。
他の値については、この製剤 仮定を禁止 上の四角で囲まれた値のアイデンティティ プログラマの一部。これができるようになります いくつかの(しかし必要ではない)共有や これらの参考文献の全てます。
これは最も一般的なことを保証します 例、動作は次のようになります 過度をかけることなく、1を希望 特に上のパフォーマンスの低下、 小型デバイス。少ないメモリが制限されました 実装かもしれない、例えば、 すべての文字やショートパンツをキャッシュ 同様の整数とlong型 -32Kの範囲 - 。+ 32K
だから、いくつかのケースで==それはないでしょう多くの他に、動作します。あなたはインスタンスが得られた方法(一般的に)権限受領することはできませんので、必ず安全であることを.equalsを使用します。
速度が要因である(ほとんど.equalsが==比較で始まる、または少なくとも、彼らが必要)、あなたは彼らが割り当てられたか島嶼地区などができ、彼らは==その後、上記の範囲に収まる場合は、安全です。
いくつかのVMは、その大きさを増大させることができるが、あなたが本当に、本当に、本当にする必要がない限り、特定のVMの動作に依存するよりものlangauge仕様で指定された最小サイズを想定する方が安全です。
等しい(オブジェクトo)メソッドの実装は、ほとんど常に
で始まりif(this == o) return true;
これequals
が本当にパフォーマンスヒットの多く真されていない場合でも==
を使用します。
私は、オブジェクト上のequals
メソッドを使用して*必ずお勧めします。
*もちろん、あなたはこのアドバイスを取るべきではない非常に数回があります。の
一般的な答えはいいえ、あなたが同じ数値のために、あなたが得るロングオブジェクトが同じであることを保証するものではありません(あなたがLong.valueOfを使用して自分自身を制限していても())。
しかし、あなたの最初の(==を使用して)参照の等価性をテストしようとし、その後、失敗した場合には、しようと等号()によって性能向上を得るということも可能です。これは、すべての追加==テストとメソッド呼び出しの比較コストにかかって...あなたの走行距離は変更になる場合がありますが、それは優れているかを確認するために、単純なループテストを試してみる価値あります。
これは、彼らが利用可能な場合は、自動箱入りの値は用途がオブジェクトをプールされたということは注目に値します。 Javaの6u13のためにこれである理由(整数)0 ==(整数)0が、(整数)128!=(整数)128
私は視覚的に結果を見たいます:
public static void main(String[] args)
{
Integer a = 126; //no boxed up conversion, new object ref
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion, new object
Integer b1 = 140; //boxed up conversion, new object
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
}
==
がオブジェクト等しいかどうか比較しながら、 equals(Object obj)
は、オブジェクト参照を比較します。 の、これまでに2つ以上のインスタンスがある場合は、のあなたはの存在したオブジェクトに等しい同等比較のためのを使用equals
必要があります。
例:
Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);
これらは、異なるオブジェクトのインスタンスであるが、整数の平等によると同等であるので、あなたはequals(Object obj)
を使用する必要があります。
public enum Gender {
MALE, FEMALE;
}
FEMALE
を使用しても安全であるように、この場合にのみ存在し==
の1つのインスタンスが存在します。