125

Javaでの等しいかどうかをテストするときString、私はいつもequals()これを使用しました。なぜなら、これが最も自然な方法のように思われるからです。結局のところ、その名前はすでにそれが何をしようとしているのかを示しています。しかし、私の同僚は最近、のcompareTo() == 0代わりに使用するように教えられたと私に言いましたequals()。これは不自然に感じ(compareTo()順序付けを提供し、平等を比較しないことを意味します)、多少危険です(compareTo() == 0すべての場合に平等を意味するわけではありませんが、私はそれが平等であることを知っていますがString)。

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

4

21 に答える 21

112

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

于 2009-10-11T18:14:31.047 に答える
37

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

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

String クラスのコードを見てみると、compareTo と equals 内のアルゴリズムは基本的に同じに見えます。私は彼の意見は単なる好みの問題であると信じており、私はあなたに同意します.あなたが知る必要があるのはストリングの同等性であり、辞書編集的にどちらが最初に来るかではない場合、私はequals.

于 2009-10-11T17:45:16.660 に答える
29

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

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

これは文字列に限らず、一般的に当てはまります。

于 2009-10-11T18:12:57.117 に答える
20

compareTo文字列の長さが異なる場合、より多くの作業を行う必要があります。equalsfalse を返すことができcompareToますが、並べ替え順序を見つけるのに十分な文字を常に調べる必要があります。

于 2009-10-11T18:28:23.610 に答える
11

文字列コンテキスト:
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
于 2012-07-07T06:58:57.150 に答える
10

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

ただしcompareTo()、通常は昇順または降順でオブジェクトを並べ替えるときに使用されるオブジェクトの順序を示しますがequals()、同等性についてのみ話し、それらが等しいかどうかを示します。

于 2010-08-05T05:36:41.053 に答える
7

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

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

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

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

compareTo() (インターフェイス Comparable から) は整数を返します。2 つのオブジェクトのどちらが他方よりも「小さい」、「等しい」、または「大きい」かをチェックします。すべてのオブジェクトを論理的に並べ替えることができるわけではないため、compareTo() メソッドが常に意味を持つとは限りません。

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

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

于 2016-05-28T08:58:13.680 に答える
6

どちらのメソッドもほぼ同じことを行うように見えますが、compareTo() メソッドはオブジェクトではなく文字列を受け取り、通常の equals() メソッドの上にいくつかの追加機能を追加します。等価性のみを気にする場合は、equals() メソッドが最良の選択です。これは、コードを確認する次のプログラマーにとってより意味があるためです。2 つの異なる関数間の時間差は、大量のアイテムをループしていない限り問題になりません。compareTo() は、コレクション内の文字列の順序を知る必要がある場合、または同じ文字シーケンスで始まる文字列間の長さの違いを知る必要がある場合に非常に役立ちます。

ソース: http://java.sun.com/javase/6/docs/api/java/lang/String.html

于 2009-10-11T17:44:53.430 に答える
5

equals()OPの場合は、選択する方法を選択する必要があります。

grepcodeのjava.lang.String のequals()との実装を見ると、2 つの文字列の等価性だけに関心がある場合は、equals の方が優れていることが簡単にわかります。compareTo()

equals():

1012   public  boolean equals(オブジェクトanObject) { 
1013 if ( this == anObject) {
1014 return true ;
1015 }
1016 if (anObject instanceof String ) {
1017 String anotherString = ( String )anObject;
1018 int n = カウント;
1019 if (n == anotherString.count) {
1020 char v1[] = 値;
1021 char v2[] = anotherString.value;
1022 整数i = オフセット;
1023 int j = anotherString.offset;
1024 while (n-- != 0) {
1025 if (v1[i++] != v2[j++])
1026 return false ;
1027 }
1028 真を返し ます。1029 } 1030 } 1031 falseを返します。1032 }




compareTo():

1174   public  int compareTo(文字列anotherString) { 
1175 int len1 = カウント;
1176 int len2 = anotherString.count;
1177 int n = 数学。(len1、len2);
1178 文字v1[] = 値;
1179 char v2[] = anotherString.value;
1180 int i = オフセット;
1181 int j = 別の文字列.offset;
1183 もし(i == j) {
1184 int k = i;
1185 intリム= n + i;
1186 ながら(k < リム) {
1187 文字c1 = v1[k];
1188 文字c2 = v2[k];
1189 if (c1 != c2) {
1190 return c1 - c2;
1191 }
1192 k++;
1193 }
1194 } else {
1195 while (n-- != 0) {
1196 char c1 = v1[i++];
1197 char c2 = v2[j++];
1198 if (c1 != c2) {
1199 return c1 - c2;
1200 }
1201 }
1202 }
1203 リターンlen1 - len2;
1204 }

文字列の 1 つが別の文字列のプレフィックスであるcompareTo()場合、辞書式順序を決定する必要があるため、 のパフォーマンスは低下しますが、equals()これ以上心配する必要はなく、すぐに false を返します。

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

  • equals()等しいかどうかをチェックし、
  • compareTo()字句順序を見つける。
于 2013-05-15T07:55:31.597 に答える
2

String.equals()instanceof演算子を呼び出すcompareTo()必要がありますが、必要ありません。instanceof私の同僚は、メソッドの呼び出し回数が多すぎるためにパフォーマンスが大幅に低下していることに気付きましたがequals()、私のテストではcompareTo()わずかに高速であることが証明されました。

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

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

于 2011-06-03T11:37:41.843 に答える
2

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

String 内の文字シーケンスの長さが一致しない場合、String が等しいということはあり得ないため、拒否ははるかに高速になります。

さらに、同じオブジェクト (論理的等価性ではなく同一性等価性) である場合も、より効率的になります。

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

于 2015-09-29T18:06:27.990 に答える
2

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

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

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

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

x と y が同一の場合、同じ「サイズ」を共有します: x.equals(y) が true の場合 => x.compareTo(y) は 0 です。

ただし、x と y が同じサイズを共有している場合でも、それらが同一であることを意味するわけではありません。

x.compareTo(y) が 0 の場合、必ずしも x.equals(y) が true であるとは限りません。

アイデンティティがサイズと異なる説得力のある例は、複素数です。絶対値で比較するとします。Z1 = a1 + b1*i と Z2 = a2 + b2*i の 2 つの複素数が与えられた場合:

Z1.equals(z2) は、a1 = a2 かつ b1 = b2 の場合にのみ true を返します。

ただし、Z1.compareTo(Z2) は、条件 a1^2 + b1^2 == a2^2 + b2^2 を満たす限り、(a1,b1) と (a2,b2) のペアに対して 0 を返します。

于 2013-11-15T07:32:00.233 に答える
2

Java で compareTo をオーバーライドする際に留意する必要がある特定の事項があります。詳細については、Java で Comparator をオーバーライドする際の注意事項を確認してください。

于 2011-11-14T14:49:26.623 に答える
1
  1. equalsパラメータとして任意のオブジェクトを取ることがcompareToできますが、文字列しか取ることができません。

  2. null にcompareToなると、例外がスローされます

  3. 差分がどこで発生したかを知りたい場合は、 を使用できますcompareTo

于 2012-02-02T02:19:11.277 に答える
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 と同じ位置に発生します。ゼロより大きい - このインスタンスは、ソート順で obj に従います。

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

たとえば、ここにアクセスできます。

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

于 2013-11-15T07:54:24.623 に答える