web-dev-qa-db-ja.com

String#equalsメソッドとString#contentEqualsメソッドの違い

String#equals メソッドと String#contentEquals メソッドの違いは何ですか?

126
Arathana

String#equals() は、Stringの内容を比較するだけでなく、他のオブジェクトがStringのインスタンスでもあるかどうかもチェックします。 String#contentEquals() は、内容(文字シーケンス)のみを比較し、not他のオブジェクトがStringのインスタンスでもあります。 a.oをカバーする CharSequence の実装である限り、どのようなものでもかまいません。 StringStringBuilderStringBufferCharBuffer など.

142
BalusC

簡単に言うと: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()は、StringStringBuilderStringBufferCharSequenceおよびこれらのすべての派生クラスの内容を比較できます。パラメーターがString型の場合、String.equals()が実行されます。

  • String.equals()はStringオブジェクトのみを比較します。他のすべてのオブジェクトタイプは等しくないと見なされます。

  • String.contentEquals()は、StringBufferStringBuilderをインテリジェントな方法で比較できます。 not重いtoString()メソッドを呼び出し、コンテンツ全体を新しいStringオブジェクトにコピーします。代わりに、基礎となるchar[]配列と比較します。これは素晴らしいことです。

35

この回答は既にdbwによって投稿されましたが、彼はそれを削除しましたが、実行時間、スローされる例外、

ソースコード String#equals および String#contentEquals を見ると、StringBuilderと他のCharSequenceを使用する_String#contentEquals_の2つのオーバーライドされたメソッドがあることが明らかです。 。
それらの違いは、

  1. _String#contentEquals_は、指定された引数がnullである場合にNPEをスローしますが、_String#equals_はfalseを返します
  2. _String#equals_は、指定された引数が_instance of String_である場合にのみコンテンツを比較します。それ以外の場合はfalseを返しますが、一方で_String#contentEquals_はインターフェースを実装するすべてのオブジェクトのコンテンツをチェックします- CharSequence
  3. また、以下に示すように渡された引数の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;
            }
        }));
    _
  4. _String#contentEquals_は、指定された引数が_String#Equals_であり、両方のStringの長さが同じでも内容が等しくない場合、_instance of String_よりも遅くなります。
    文字列が_String s = "madam"_および_String argPassed = "madan"_の場合、s.contentEquals(argPassed)はほぼ2倍になりますs.equals(argPassed)と比較したこの場合の実行時間

  5. コンテンツの長さが両方の文字列で同じではない場合、ほとんどすべての場合、関数_String#contentEquals_のパフォーマンスは_String#Equals_よりも優れています。

彼の答えに追加するもう一つのポイント

  1. Stringオブジェクトの_String#contentEquals_もStringBuilderの内容と比較して適切な結果を提供しますが、_String#Equals_はfalseを返します
29
Prateek

contentEquals(CharSequence cs)

  • インターフェイス_Java.lang.CharacterSequence_の任意の実装インスタンスで指定された文字列値の等価性を確認できます(例、CharBufferSegmentStringStringBufferStringBuilder

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);
    }
}
_
13
Amit Sharma

equals()およびcontentEquals()は、2つのStringおよびstringsstringと比較するStringBufferクラスの2つのメソッドです。

contentEquals()のパラメーターはStringBufferおよびString(charSequence)です。 equals()は、2つのstringscontentEquals()の比較に使用され、StringStringBufferの内容の比較に使用されます。

メソッドcontentEqualsequals

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
8
Asfab

contentEquals()メソッドのチェックは、ある種のcharシーケンスであるStringStringBufferなどの間で内容が同じであることを確認します。

6
fastcodejava

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よりも高速です。オブジェクトインスタンスのチェックの前に長さが比較されるためです。

6
Anirban Pal

ところで、違いの歴史的な理由は、Stringには元々スーパークラスがなかったため、String.equals()は引数としてStringを取ることです。 CharSequenceがStringのスーパークラスとして導入されたとき、すべてのCharSequence実装で機能する独自の同等性テストが必要であり、Stringで既に使用されているequals()と衝突しないため、CharSequence.contentEquals( )、Stringによって継承されます。

CharSequenceがJava 1.0に存在する場合、ProBalbyはCharSequence.equals()のみを持ち、Stringはそれを単に実装します。

ああ、進化する言語の喜び...

5
keshlam