String#equals
メソッドと String#contentEquals
メソッドの違いは何ですか?
String#equals()
は、Stringの内容を比較するだけでなく、他のオブジェクトがString
のインスタンスでもあるかどうかもチェックします。 String#contentEquals()
は、内容(文字シーケンス)のみを比較し、not他のオブジェクトがString
のインスタンスでもあります。 a.oをカバーする CharSequence
の実装である限り、どのようなものでもかまいません。 String
、 StringBuilder
、 StringBuffer
、 CharBuffer
など.
簡単に言うと:String.contentEquals()
はString.equals()
の賢い兄弟です。実装ではString.equals()
よりも自由に使えるからです。
別のString.contentEquals()
メソッドがある理由はいくつかあります。私が考える最も重要な理由は:
equals
メソッドは再帰的でなければなりません。つまり、x.equals(y) == y.equals(x)
。これは、aString.equals(aStringBuffer)
がaStringBuffer.equals(aString)
と同じでなければならないことを意味します。これには、Java API開発者がStringBuffer、StringBuilder、CharSequenceのequals()
メソッドで文字列の特別な実装を行う必要があります。これは混乱になります。そして、それはString.contentEquals
が入ってくるときです。これはスタンドアロンメソッドで、notは厳密な要件とルールに従いますです= Object.equals
の場合。このようにして、「等しいコンテンツ」の意味をより自由に実装できます。これにより、たとえば、StringBufferとStringの間でインテリジェントな比較を行うことができます。
そして、正確に何が違うのかと言うと:
String.contentEquals()
は、String
、StringBuilder
、StringBuffer
、CharSequence
およびこれらのすべての派生クラスの内容を比較できます。パラメーターがString型の場合、String.equals()
が実行されます。
String.equals()
はStringオブジェクトのみを比較します。他のすべてのオブジェクトタイプは等しくないと見なされます。
String.contentEquals()
は、StringBuffer
とStringBuilder
をインテリジェントな方法で比較できます。 not重いtoString()
メソッドを呼び出し、コンテンツ全体を新しいStringオブジェクトにコピーします。代わりに、基礎となるchar[]
配列と比較します。これは素晴らしいことです。
この回答は既にdbwによって投稿されましたが、彼はそれを削除しましたが、実行時間、スローされる例外、
ソースコード String#equals および String#contentEquals を見ると、StringBuilder
と他のCharSequence
を使用する_String#contentEquals
_の2つのオーバーライドされたメソッドがあることが明らかです。 。
それらの違いは、
String#contentEquals
_は、指定された引数がnull
である場合にNPEをスローしますが、_String#equals
_はfalse
を返しますString#equals
_は、指定された引数が_instance of String
_である場合にのみコンテンツを比較します。それ以外の場合はfalse
を返しますが、一方で_String#contentEquals
_はインターフェースを実装するすべてのオブジェクトのコンテンツをチェックします- CharSequence
。また、以下に示すように渡された引数のequals
メソッドをオーバーライドすることで、_String#contentEquals
_が間違った結果または必要な結果を返すようにコードを調整できますが、_String#equals
_でこれらの調整を行うことはできません。
以下のコードは、true
に3文字のs
が含まれている限り、常にstring
を生成します。
_ String s= new String("abc");// "abc";
System.out.println(s.contentEquals(new CharSequence()
{
@Override
public CharSequence subSequence(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int length() {
// TODO Auto-generated method stub
return 0;
}
@Override
public char charAt(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean equals(Object obj)
{
return true;
}
}));
_
_String#contentEquals
_は、指定された引数が_String#Equals
_であり、両方のString
の長さが同じでも内容が等しくない場合、_instance of String
_よりも遅くなります。
例文字列が_String s = "madam"
_および_String argPassed = "madan"
_の場合、s.contentEquals(argPassed)
はほぼ2倍になりますs.equals(argPassed)
と比較したこの場合の実行時間
コンテンツの長さが両方の文字列で同じではない場合、ほとんどすべての場合、関数_String#contentEquals
_のパフォーマンスは_String#Equals
_よりも優れています。
彼の答えに追加するもう一つのポイント
String
オブジェクトの_String#contentEquals
_もStringBuilder
の内容と比較して適切な結果を提供しますが、_String#Equals
_はfalse
を返しますcontentEquals(CharSequence cs)
:
Java.lang.CharacterSequence
_の任意の実装インスタンスで指定された文字列値の等価性を確認できます(例、CharBuffer
、Segment
、String
、StringBuffer
、StringBuilder
)equals(Object anObject)
:
Java.lang.String
_ onlyの任意のインスタンスで、指定された文字列値の等価性をチェックできますRTFC:)
ソースを読むことがそれを理解するための最良の方法であるため、私は両方のメソッドの実装を共有しています(jdk 1.7.0_45現在)
_public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
_
_public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
_
String#contentEquals()の別のメソッドがあります:
_public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
_
equals()
およびcontentEquals()
は、2つのString
およびstrings
をstring
と比較するStringBuffer
クラスの2つのメソッドです。
contentEquals()
のパラメーターはStringBuffer
およびString(charSequence)
です。 equals()
は、2つのstrings
とcontentEquals()
の比較に使用され、String
とStringBuffer
の内容の比較に使用されます。
メソッドcontentEquals
とequals
は
public boolean contentEquals(Java.lang.StringBuffer);
public boolean contentEquals(Java.lang.CharSequence);
public boolean equals(Object o)
以下は両方の方法を説明するコードです
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works Nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works Nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works Nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works Nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works Nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
出力:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
contentEquals()
メソッドのチェックは、ある種のcharシーケンスであるString
、StringBuffer
などの間で内容が同じであることを確認します。
String#equalsはObjectを引数として受け取り、それがStringオブジェクトのインスタンスであるかどうかを確認します。引数オブジェクトが文字列オブジェクトの場合、文字ごとにコンテンツを比較します。両方の文字列オブジェクトのコンテンツが同じ場合にtrueを返します。
String#contentEqualsは、CharSequenceインターフェイスを引数として取ります。 CharSequenceは、i)Stringクラスまたは(ii)AbstractStringBuilder(StringBufferの親クラス、StringBuilder)を使用して、2つの方法で実装できます。
contentEquals()では、オブジェクトインスタンスのチェック前に長さが比較されます。長さが同じ場合、引数オブジェクトがAbstractStringBuilderのインスタンスであるかどうかをチェックします。そうである場合(つまり、StringBufferまたはStringBuilder)、コンテンツは文字ごとにチェックされます。引数がStringオブジェクトのインスタンスの場合、String#equalsはString#contentEqualsから呼び出されます。
要するに、
String#equals引数がStringオブジェクトの場合も、文字ごとにコンテンツを比較します。そしてString#contentEqualsは、引数オブジェクトがCharSequenceインターフェースを実装している場合のコンテンツを比較します。
String#contentEqualsは内部的にStringオブジェクトのString#equalsを呼び出すため、2つの同じ長さの文字列コンテンツを比較する場合、String#contentEqualsは遅くなります。
内容の長さが異なるオブジェクト(「abc」と「abcd」など)を比較する場合、String#contentEqualsはString#equalsよりも高速です。オブジェクトインスタンスのチェックの前に長さが比較されるためです。
ところで、違いの歴史的な理由は、Stringには元々スーパークラスがなかったため、String.equals()は引数としてStringを取ることです。 CharSequenceがStringのスーパークラスとして導入されたとき、すべてのCharSequence実装で機能する独自の同等性テストが必要であり、Stringで既に使用されているequals()と衝突しないため、CharSequence.contentEquals( )、Stringによって継承されます。
CharSequenceがJava 1.0に存在する場合、ProBalbyはCharSequence.equals()のみを持ち、Stringはそれを単に実装します。
ああ、進化する言語の喜び...