web-dev-qa-db-ja.com

Java文字列:compareTo()vs. equals()

JavaのStringの等価性をテストするとき、私は常にequals()を使用しました。これは、私にとってこれが最も自然な方法だと思われるためです。結局のところ、その名前はすでに何をしようとしているのかを示しています。しかし、私の同僚は最近、compareTo() == 0の代わりにequals()を使用するように教えられたと言った。これは不自然に感じます(compareTo()は順序付けを提供し、平等を比較することを意図していないため)、さらに危険です(compareTo() == 0は、String ) 私に。

彼は、StringcompareTo()の代わりにequals()を使用するように教えられた理由を知りませんでした。また、理由も見つかりませんでした。これは本当に個人的な好みの問題ですか、それともどちらの方法にも本当の理由がありますか?

110
Thomas Lötzer

違いは、"foo".equals((String)null)がNullPointerExceptionをスローする間に"foo".compareTo((String)null) == 0がfalseを返すことです。したがって、文字列であっても常に互換性があるとは限りません。

97
waxwing

2つの主な違いは次のとおりです。

  1. equalsは任意のオブジェクトをパラメーターとして受け取りますが、compareToはストリングのみを受け取ります。
  2. equalsは、それらが等しいかどうかのみを示しますが、compareToは、文字列が辞書式に比較される方法に関する情報を提供します。

Stringクラスのコード を見て、compareToとequals内のアルゴリズムは基本的に同じに見えます。私は彼の意見は単なる好みの問題であり、あなたが同意する必要があると思います-あなたが知っている必要があるのは文字列の平等であり、どれが辞書式に最初に来るかではないなら、私はequalsを使用します。

27
Kaleb Brasee

同等性を比較するときは、equals()を使用する必要があります。これは、意図を明確に表現するためです。

compareTo()には、Comparableインターフェイスを実装するオブジェクトでのみ機能するという追加の欠点があります。

これは、文字列だけでなく、一般的に適用されます。

26
starblue

compareToは、文字列の長さが異なる場合、より多くの作業を行います。 equalsはfalseを返すことができますが、compareToは常にソート順を見つけるのに十分な文字を調べる必要があります。

16
robinr

compareTo<T>は汎用引数Tを取るため、compareTo()は文字列だけでなく他のオブジェクトにも適用されます。文字列は、Comparableインターフェイスを実装することでcompareTo()メソッドを実装したクラスの1つです。(compareTo()は、同等のインターフェースのメソッドです)。 したがって、どのクラスでもComparableインターフェースを自由に実装できます。

しかし、compareTo()はオブジェクトの順序を与えます、通常は昇順または降順でオブジェクトをソートする際に使用されますが、equals()は話すだけです平等について、それらが等しいかどうかを言います。

10
apurva jadhav

文字列コンテキスト内:
compareTo:2つの文字列を辞書式に比較します。
equals:この文字列を指定されたオブジェクトと比較します。

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
10
VirtualLogic

equals()compareTo()よりも効率的です。

CompareToとequalsの非常に重要な違い:

"myString".compareTo(null);  //Throws Java.lang.NullPointerException
"myString".equals(null);     //Returns false

equals() 2つのオブジェクトが同じかどうかを確認し、ブール値を返します。

compareTo()(Comparableインターフェイスから)整数を返します。 2つのオブジェクトのどちらが「より小さい」、「等しい」、または「より大きい」かをチェックします。すべてのオブジェクトを論理的に順序付けできるわけではないため、compareTo()メソッドは必ずしも意味をなさない場合があります。

Equals()は、compareTo()が行うオブジェクト間の順序を定義しないことに注意してください。

ここで、両方のメソッドのソースコードを確認して、Math計算を含むcompareToよりもequalsの方が望ましいと結論付けることをお勧めします。

7
Jaimin Patel

equals()は、OPの場合に選択するメソッドである必要があります。

grepcodeのJava.lang.Stringequals()およびcompareTo()の実装を見ると、2つの文字列の等価性だけを考慮する場合、equalsの方が優れていることが簡単にわかります。

__関数__:

1012  ブール値 equals( Object  anObject){
101  もし (この == anObject){
1014  帰る本当;
1015 }
1016  もし (anObject instanceof  String ){
1017String anotherString =( String )anObject;
1018  int n =カウント;
1019  もし (n == anotherString.count){
102  チャー v1 [] =値;
1021  チャー v2 [] = anotherString.value;
1022  int i =オフセット;
102  int j = anotherString.offset;
1024  ながら (n--!= 0){
1025  もし (v1 [i ++]!= v2 [j ++])
1026  帰るfalse;
1027 }
1028  帰る本当;
1029 }
10 }
1031  帰るfalse;
1032 }

およびequals()

1174  int compareTo( String  anotherString){
1175  int len1 =カウント;
1176  int len2 = anotherString.count;
1177  int n =数学. min (len1、len2);
1178  チャー v1 [] =値;
1179  チャー v2 [] = anotherString.value;
118  int i =オフセット;
1181  int j = anotherString.offset;
118  もし (i == j){
1184  int k = i;
1185  int lim = n + i;
1186  ながら (k <lim){
1187  チャー c1 = v1 [k];
1188  チャー c2 = v2 [k];
1189  もし (c1!= c2){
119  帰る c1-c2;
1191 }
1192 k ++;
119 }
1194else {
1195  ながら (n--!= 0){
1196  チャー c1 = v1 [i ++];
1197  チャー c2 = v2 [j ++];
1198  もし (c1!= c2){
1199  帰る c1-c2;
12 }
1201 }
1202 }
12  帰る len1-len2;
1204 }

文字列の1つが別の文字列の接頭辞である場合、compareTo()は辞書式の順序を決定する必要があるため、compareTo()はパフォーマンスを低下させますが、equals()はそれ以上心配せず、すぐにfalseを返します。

私の意見では、これら2つを意図したとおりに使用する必要があります。

  • equals()が等しいかどうかを確認し、
  • compareTo()字句順を見つける。
5
prk

どちらのメソッドもほとんど同じことをしているように見えますが、compareTo()メソッドはObjectではなくStringを受け取り、通常のequals()メソッドの上にいくつかの追加機能を追加します。あなたが気にするのが平等だけなら、equals()メソッドが最良の選択です。なぜならあなたのコードを見る次のプログラマにとってより理にかなっているからです。 2つの異なる関数の時間差は、大量のアイテムをループしている場合を除いて重要ではありません。 compareTo()は、コレクション内の文字列の順序を知る必要がある場合、または同じ文字シーケンスで始まる文字列間の長さの違いを知る必要がある場合に非常に便利です。

ソース: http://Java.Sun.com/javase/6/docs/api/Java/lang/String.html

5
Scott M.

equals()は、2つの文字列が等しいかどうかをチェックします。ブール値を返します。 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
2
Ankit Uniyal

Javaのc​​ompareToをオーバーライドする際に留意する必要がある特定の事項があります。 Comparetoはequalsと一致している必要があり、整数フィールドがオーバーフローする可能性があるため、減算を使用して整数フィールドを比較しないでください。 JavaでComparatorをオーバーライドするときに覚えておくべきこと を確認してください。

2
Seema Kiran

String.equals()にはinstanceofの呼び出しが必要ですが、compareTo()には必要ありません。同僚は、equals()メソッドでの過剰な数のinstanceof呼び出しに起因する大きなパフォーマンスの低下に気付きましたが、私のテストではcompareTo()がわずかに高速であることが証明されました。

ただし、Java 1.6を使用していました。他のバージョン(または他のJDKベンダー)では、違いが大きくなる可能性があります。

このテストでは、1000個の要素配列の各文字列を10回繰り返して比較しました。

2
Danubian Sailor

EqualsはcompareToよりも効率的です。

文字列の文字シーケンスの長さが一致しない場合、文字列が等しい方法がないため、拒否がはるかに高速になります。

さらに、同じオブジェクト(論理的等式ではなく同一性)であれば、より効率的です。

また、hashCodeキャッシングも実装している場合、hashCodeが一致しない場合に、等しくないものを拒否するのがさらに速くなる可能性があります。

2
  • equals:同等性のチェックと重複の制限に必要です。 Javaライブラリの多くのクラスは、重複を見つけたい場合にこれを使用します。例えばHashSet.add(ob1)は、存在しない場合にのみ追加されます。したがって、このようなクラスを拡張する場合は、equals()をオーバーライドします。

  • compareTo:要素の順序付けに必要です。安定したソートを行うには、平等が必要なので、戻り値0があります。

1
Dillip Rout
  1. equalsは任意のオブジェクトをパラメーターとして使用できますが、compareToはストリングのみを使用できます。

  2. nullになると、compareToは例外をスローします

  3. 差分の発生場所を知りたい場合は、compareToを使用できます。

1
littletiger

これはネクロマンシーの実験です:-)

ほとんどの回答では、パフォーマンスとAPIの違いを比較しています。彼らは、2つの操作が単に異なるセマンティクスを持っているという基本的な点を見逃しています。

あなたの直感は正しいです。 x.equals(y)は、x.compareTo(y)== 0と互換性がありません。最初はIDを比較し、もう1つは 'size'の概念を比較します。多くの場合、特にプリミティブ型では、これら2つが同じ位置にあることは事実です。

一般的なケースは次のとおりです。

Xとyが同一の場合、それらは同じ「サイズ」を共有します:x.equals(y)がtrue => 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)は、a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2の条件を満たす限り、(a1、b1)および(a2、b2)のペアに対して0の無限の数のペアを返します。

1
Vitaliy

「等しい」はオブジェクトを比較し、trueまたはfalseを返し、「比較」はtrueの場合は0、falseの場合は数値[> 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://docs.Oracle.com/javase/7/docs/api/Java/lang/Comparable.html

等しいドキュメント: https://docs.Oracle.com/javase/7/docs/api/Java/lang/Object.html#equals(Java.lang.Object)

0
David Hackro

equals and equalingnorecase Stringのメソッドはtrueとfalseを返すので、文字列オブジェクトの値を比較したい場合に便利ですが、compareToとcompareToIgnoreCaseメソッドを実装する場合はソートの場合に役立つ、正、負、ゼロの値を返します。

0
Prakhar Aditya

ここでは、compareTo() over equals()を使用する際に、compareToが 'Comparable'インターフェイスを実装するクラスで機能することが重要です。そうでない場合は、NullPointerExceptionがスローされます。 StringクラスはComparableインターフェイスを実装しますが、StringBufferStringオブジェクトでは"foo".compareTo("doo")を使用できますが、StringBufferオブジェクトでは使用できません。

0
Pratik

等しい-

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.yquals(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

while compareTo-

現在のインスタンスを同じタイプの別のオブジェクトと比較し、現在のインスタンスが他のオブジェクトとソート順で同じ位置に先行するか、後続するか、発生するかを示す整数を返します。

戻ります-

ゼロ未満-このインスタンスは、ソート順でobjに先行します。ゼロ-このインスタンスは、objと同じ並べ替え順序で発生します。ゼロより大きい-このインスタンスは、ソート順でobjの後に続きます。

オブジェクトがインスタンスと同じ型でない場合、ArgumentExceptionをスローできます。

たとえば、こちらをご覧ください。

したがって、compareToの代わりにEqualsを使用することをお勧めします。

0
Prabhat Jain