Java 文字列:CompareTo() と等しい()
質問
等しいかどうかをテストするとき String
私がいつも使っているJavaの equals()
なぜなら、私にとってこれが最も自然な方法であるように思えるからです。結局のところ、その名前はすでにその目的を示しています。しかし、最近私の同僚が私に次のように教えられたと言いました。 compareTo() == 0
の代わりに equals()
. 。これは不自然に感じます( compareTo()
これは順序を提供することを目的としており、等しいかどうかを比較するものではありません)、多少危険ですらあります (なぜなら、 compareTo() == 0
すべての場合において平等であることはわかっていますが、必ずしも平等であるとは限りません。 String
さん)私に。
彼はなぜその使い方を教えられたのか分かりませんでした compareTo()
の代わりに equals()
のために String
と、私も理由が見つかりませんでした。これは本当に個人的な好みの問題なのでしょうか、それともどちらの方法にも本当の理由があるのでしょうか?
解決
の違いは"foo".equals((String)null)
は、NullPointerExceptionがスローながら"foo".compareTo((String)null) == 0
がfalseを返すということです。だから彼らは、さらに文字列のために、常に互換性がありません。
他のヒント
主な違いは次の 2 つです。
equals
任意のオブジェクトをパラメータとして受け取りますが、compareTo
文字列のみを受け取ります。equals
等しいかどうかを示すだけですが、compareTo
文字列が辞書編集的にどのように比較されるかについての情報を提供します。
見てみました Stringクラスコード, 、compareToとequals内のアルゴリズムは基本的に同じように見えます。私は彼の意見は単なる好みの問題だと信じています、そして私もあなたに同意します。もしあなたが知る必要があるのが文字列の同等性だけであり、辞書編集的にどれが最初に来るかではないのであれば、私は次のようにします。 equals
.
あなたは、equals()
を使用する必要があります。
compareTo()
は、それが唯一のComparable
インターフェイスを実装するオブジェクト上で動作することを追加欠点を持っています。
これは文字列のためだけでなく、一般的に適用されます。
compareTo
は、文字列の長さが異なる場合は、より多くの仕事をしますか持っています。 equals
は常にソート順を見つけるために、十分な文字を調べなければならないがcompareTo
はちょうど、falseを返すことができます。
compareTo()
文字列だけでなく他のオブジェクトにも適用されます。 compareTo<T>
一般的な引数を取ります T
. 。String は、 compareTo()
メソッドを実装することで、 Comparable
インターフェース。(compareTo() は比較可能なインターフェイスのメソッドです)。 したがって、どのクラスでも Comparable インターフェイスを自由に実装できます。
しかし compareTo()
オブジェクトの順序を指定します, 、通常、オブジェクトを昇順または降順で並べ替える際に使用されます。 equals()
平等についてのみ話します そしてそれらが等しいかどうかを言います。
文字列コンテキストで:
compareTo:2つの文字列を辞書比較
。
等しい:指定されたオブジェクトにこの文字列を比較し
のcompareToは(同じインデックスで)それらの文字で2つの文字列を比較し、それに応じて(正または負)の整数を返す。
String s1 = "ab";
String s2 = "ab";
String s3 = "qb";
s1.compareTo(s2); // is 0
s1.compareTo(s3); // is -16
s3.compareTo(s1); // is 16
)(等しくの の、より効率的であることができるののcompareTo()の
のcompareToとの間で非常に重要な違いが等しくます:
"myString".compareTo(null); //Throws java.lang.NullPointerException
"myString".equals(null); //Returns false
のに等しい()の2つのオブジェクトが同じであるかどうか、およびブール値を返すかどうかを確認します。
ののcompareTo()の(インターフェース同等の)整数を返します。これは、他の「より大きい」「等しい」または「未満」である二つのオブジェクトのどのチェックします。すべてのオブジェクトは、論理的にそうのcompareTo()メソッドは、常に意味がない、注文することができません。
()に等しい注のcompareTo()が行うオブジェクト間の順序を定義していません。
今、私はあなたがそれはいくつかの数学の計算を必要とするのcompareTo以上が望ましい等しい締結する両方の方法のソースコードを確認することをお勧めします。
かなり両方の方法で同じことを行うことが表示されますが、のcompareTo()メソッドは文字列ではなく、オブジェクトを取り込み、通常のequals()メソッドの上にいくつかの追加機能を追加します。あなたが気にすべてが平等である場合には、等号()メソッドは、それはあなたのコードを見て取り、次のプログラマに、より理にかなっているという理由だけで、最良の選択です。あなたが項目のいくつかの巨大な量をループしていない限り、2つの異なる機能間の時間差は問題ではないはず。あなたは同じ文字シーケンスで始まる文字列の長さの差を理解する必要がある場合、あなたは、コレクション内の文字列の順序を知っている必要がありますかときのcompareTo()は本当に便利です。
ソース:ます。http://java.sun。 COM /のJava SE / 6 /ドキュメント/ API / Javaの/ LANG / String.htmlする
equals()
OP の場合は、この方法を選択する必要があります。
の実装を見ると、 equals()
そして compareTo()
で grepcode の java.lang.String, 2 つの String が等しいかどうかだけを考える場合、equals の方が優れていることが簡単にわかります。
equals()
:
1012 公共 ブール値 equals(物体 anObject) {
1013 もし (これ == anObject) {
1014 戻る 真実;
1015 }
1016 もし (anObject インスタンスの 弦) {
1017 弦 anotherString = (弦)anObject;
1018 整数 n = count;
1019 もし (n == anotherString.count) {
1020 チャー v1[] = value;
1021 チャー v2[] = anotherString.value;
1022 整数 i = offset;
1023 整数 j = anotherString.offset;
1024 その間 (n-- != 0) {
1025 もし (v1[i++] != v2[j++])
1026 戻る 間違い;
1027 }
1028 戻る 真実;
1029 }
1030 }
1031 戻る 間違い;
1032 }
そして compareTo()
:
1174 公共 整数 compareTo(弦 anotherString) {
1175 整数 len1 = count;
1176 整数 len2 = anotherString.count;
1177 整数 n = Math.分(len1, len2);
1178 チャー v1[] = value;
1179 チャー v2[] = anotherString.value;
1180 整数 i = offset;
1181 整数 j = anotherString.offset;
1183 もし (i == j) {
1184 整数 k = i;
1185 整数 lim = n + i;
1186 その間 (k < lim) {
1187 チャー c1 = v1[k];
1188 チャー c2 = v2[k];
1189 もし (c1 != c2) {
1190 戻る c1 - c2;
1191 }
1192 k++;
1193 }
1194 } それ以外 {
1195 その間 (n-- != 0) {
1196 チャー c1 = v1[i++];
1197 チャー c2 = v2[j++];
1198 もし (c1 != c2) {
1199 戻る c1 - c2;
1200 }
1201 }
1202 }
1203 戻る len1 - len2;
1204 }
文字列の 1 つが別の文字列のプレフィックスである場合、 compareTo()
辞書編集上の順序を決定する必要があるため、さらに悪いことになります。 equals()
もう心配する必要はなく、すぐに false を返します。
私の意見では、これら 2 つは意図されたとおりに使用する必要があります。
equals()
等しいかどうかを確認し、compareTo()
語彙の順序を見つけます。
は、JavaなどでのcompareToをオーバーライドしながら、心に留めておく必要がある特定のものがあります。彼らはオーバーフローすることができるように、整数フィールドを比較するために使用すべきではないのcompareToは等しいと減算と一致しなければなりません。 Javaののコンパレータをオーバーライドしながら、覚えて物事をチェックします詳細ます。
等号は、その後のcompareToより効率的にすることができます。
文字列内の文字列の長さが一致しない場合は、拒否がはるかに高速になりますので、文字列が等しい方法はありません。
それは同じオブジェクト(アイデンティティの平等ではなく、論理等価)である場合は、また、それはまた、より効率的になります。
彼らはまたのhashCodeキャッシュを実装した場合は、それがさらに高速の場合には非等しい拒否することができ、そのハッシュコードの一致していません。
String.equals()
呼び出す必要があります instanceof
演算子 compareTo()
必要ありません。私の同僚は、過剰な数が原因でパフォーマンスが大幅に低下することに気づきました。 instanceof
電話をかける equals()
ただし、私のテストで証明された方法 compareTo()
ほんの少しだけ速くなります。
ただし、私は Java 1.6 を使用していました。他のバージョン (または他の JDK ベンダー) では、違いがさらに大きくなる可能性があります。
テストでは、1000 個の要素配列内の文字列をそれぞれ比較し、10 回繰り返しました。
のequals()をチェックする2つの文字列が同じであるか、またはnot.Itはブール値を返すかどうか。 他の文字列object.Itに大きいか小さい文字列オブジェクトがに等しいかどうかのcompareTo()のチェックは、その結果得られます: 1文字列オブジェクトが大きい場合 0の両方が等しい場合 -1文字列が他の文字列よりも小さい場合、
EQます:
String a = "Amit";
String b = "Sumit";
String c = new String("Amit");
System.out.println(a.equals(c));//true
System.out.println(a.compareTo(c)); //0
System.out.println(a.compareTo(b)); //1
equals
任意のオブジェクトをパラメータとして受け取ることができますが、compareTo
文字列のみを取ることができます。null になったとき、
compareTo
例外をスローしますどこで差分が発生したかを知りたい場合は、次を使用できます
compareTo
.
このは死霊術における実験である: - )
ほとんどの答えは、パフォーマンスとAPIの違いを比較します。彼らは二つの操作が簡単に異なる意味を持っていることを基本的なポイントを見逃しています。
あなたの直感は正しいです。 x.equals(y)はx.compareTo(Y)== 0と交換可能ではありません。 他には「大きさ」の概念を比較しながら、最初は、アイデンティティを比較します。これは、これら2つの共整列、その多くの場合、特にプリミティブ型も同様である。
一般的な場合は、このです:
XおよびYが同一である場合、は、それらが同一の 'サイズ' を共有する:x.equals(y)が真である場合=> x.compareTo(y)は0
xとyの共有同じサイズは、それが意味するものではない場合は、しかし、それらは同一である。
x.compareTo(y)が0であれば、必ずしもx.equals(y)を意味するものではない事実である。
アイデンティティはサイズと異なる魅力的な例は、複素数になります。比較はその絶対値で行われることを前提としています。だから、2つの複素数を与えられた:Z1 = A1 + B1 * iとZ2 = A2 + B2 * I:
Z1.equals(Z2)とのみ、A1 = A2およびB1 = B2であればtrueを返します。
しかしながらZ1.compareTo(Z2)は0を返し、であれば、条件A1を満たすように(A1、B1)及び(A2、B2)ペアの無限数^ 2 + B1 ^ 2 == A2 ^ 2 + B2 ^ 2。
equals
:等価性をチェックし、重複を制限するために必要です。Java ライブラリの多くのクラスは、重複を見つけたい場合にこれを使用します。例えばHashSet.add(ob1)
それが存在しない場合にのみ追加されます。したがって、このようにいくつかのクラスを拡張している場合は、オーバーライドしてくださいequals()
.compareTo
:要素の順序付けに必要です。繰り返しになりますが、安定した並べ替えには等価性が必要なので、0 が返されます。
等しい -
1- GetHashCode メソッドをオーバーライドして、型がハッシュ テーブル内で正しく機能できるようにします。
2- Equals メソッドの実装で例外をスローしないでください。代わりに、null 引数に対して false を返します。
3-
x.Equals(x) returns true.
x.Equals(y) returns the same value as y.Equals(x).
(x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.
x.Equals(y) を連続して呼び出すと、x と y によって参照されるオブジェクトが変更されない限り、同じ値が返されます。
x.Equals(null) returns false.
4- 一部の種類のオブジェクトでは、参照の等価性ではなく、値の等価性を Equals でテストすることが望ましいです。このような Equals の実装は、2 つのオブジェクトが同じ値を持つ場合、たとえ同じインスタンスでなくても true を返します。
例えば -
Object obj1 = new Object();
Object obj2 = new Object();
Console.WriteLine(obj1.Equals(obj2));
obj1 = obj2;
Console.WriteLine(obj1.Equals(obj2));
出力:-
False
True
その間 比較対象 -
現在のインスタンスを同じタイプの別のオブジェクトと比較し、現在のインスタンスがソート順で他のオブジェクトより前か後か、または同じ位置にあるかどうかを示す整数を返します。
返されるのは -
0 未満 - このインスタンスはソート順で obj より前にあります。ゼロ - このインスタンスは、ソート順で obj と同じ位置に発生します。0 より大きい - このインスタンスは、ソート順で obj の後に続きます。
オブジェクトがインスタンスと同じ型ではない場合、ArgumentException がスローされる可能性があります。
たとえば、ここにアクセスできます。
したがって、compareTo の代わりに Equals を使用することをお勧めします。
オブジェクトを比較し、trueまたはfalseを返すと「等しいです」 真または数値の場合はfalseの場合は、[0 <]または[0>]を返す0「との比較」 ここでの例:
<!-- language: lang-java -->
//Objects Integer
Integer num1 = 1;
Integer num2 = 1;
//equal
System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));
//New Value
num2 = 3;//set value
//diferent
System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));
の結果:
num1.equals(num2) =true
num1.compareTo(num2) =0
num1.equals(num2) =false
num1.compareTo(num2) =-1
ドキュメントと比較:ます。https://ドキュメント。 oracle.com/javase/7/docs/api/java/lang/Comparable.htmlする
ドキュメントは等しい:<のhref = "https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)" のrel = "nofollowを「> https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)メソッドの
compareTo()
がスローされます「同等」インターフェイスを実装するクラスのための作品をequals()
compareTo
上NullPointerException
を使用しながら、ここでは一つのことが重要です。 String
は、したがって、あなたがStringBuffer
オブジェクトではなく"foo".compareTo("doo")
オブジェクトにString
を使用することができていない間StringBuffer
クラスはComparableインタフェースを実装しています。
私は/あなたが文字列オブジェクトの値を比較したい場合は文字列のを等しく、equalingnorecase の方法が有用であるtrueとfalseを返すと信じて、しかし、ののcompareToとcompareToIgnoreCaseを実装した場合の< strong>の方法は、ソートの場合に有用であろう、正、負、ゼロの値を返します。