Javaで文字列を比較するにはどうすればよいですか?


724

これまで==、プログラムで演算子を使用して、すべての文字列を比較してきました。しかし、私はバグに遭遇し、そのうちの1つを.equals()代わりに変更して、バグを修正しました。

ある==悪いですか?いつ使用すべきか、使用すべきでないか?違いは何ですか?


12
また、.equals()メソッドをオーバーライドする場合は、必ず.hashcode()メソッドをオーバーライドするようにしてください。そうしないと、等価関係b / wとハッシュコードに違反することになります。詳細については、java docを参照してください。
Nageswaran 2013年

==オブジェクトでの動作の理由に関する私の説明へのリンクを残す:stackoverflow.com/a/19966154/2284641
Johannes H.

==javaには文字列プールがあり、よく使用される文字列のメモリ参照を再利用しようとするため、時々動作します。しかし==、値ではなくオブジェクトが等しいことを比較します...したがって.equals()、使用したい適切な使用法はそうです。
James Oravec 2013年

==を使用して文字列が同じかどうかをテストすることは絶対に避けてください。ただし、微妙なエラーを追跡し、Java文字列の内部処理の複雑さを研究することを楽しんでいる場合を除きます。"12"=="1"+2は(おそらく)falseです
Flight Odyssey

回答:


5561

== 参照の等価性(同じオブジェクトかどうか)をテストします。

.equals() 値が等しいかどうかをテストします(論理的に「等しい」かどうか)。

Objects.equals()null呼び出す前にチェックする.equals()ので、その必要はありません(JDK7以降で利用可能、Guavaでも利用可能)。

したがって、2つの文字列が同じ値であるかどうかをテストする場合は、おそらく使用する必要がありますObjects.equals()

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

ほとんどの場合、使用したいObjects.equals()。でレアあなたは状況を知っているあなたが扱っているインターンの文字列、あなたがすることができます使用します==

JLS 3.10.5。文字列リテラル

さらに、文字列リテラルは常にclassの同じインスタンスを参照しますString。これは、文字列リテラル、またはより一般的には定数式(§15.28)の値である文字列が、メソッドを使用して一意のインスタンスを共有するために「インターン」されるためString.internです。

同様の例は、JLS 3.10.5-1にもあります。

考慮すべきその他の方法

大文字と小文字を区別しないString.equalsIgnoreCase()の値の等価性。

String.contentEquals()String、のコンテンツを任意のコンテンツと比較しますCharSequence(Java 1.5以降で使用可能)。等価比較を行う前にStringBufferなどをStringに変換する必要をなくし、nullチェックはそのままにしておきます。


3
==が参照の等価性をチェックする場合、なぜn == 5が意味をなすのですか?5は変数ではありません
Hrit Roy

2
@HritRoy は、変数==をチェックするためです。オブジェクトがある場合、オブジェクトを参照する変数には、オブジェクトの参照がvalueとして含まれます。したがって、2つの変数をで比較するときに参照を比較し==ます。などのプリミティブデータ型を比較す​​るint場合も同じです。タイプの変数intは、値として整数を持ちます。したがって、をint使用して2つのの値を比較します==。場合はint、変数や魔法数の値であり、重要ではありません。加えて:参照が何もなく、メモリを指す番号ではありません。
akuzminykh

718

==オブジェクト参照を.equals()テストし、文字列値をテストします。

==Javaは、同じインライン文字列が実際に同じオブジェクトであることを確認するために、舞台裏の処理を行うため、値を比較しているように見えることがあります。

例えば:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

ただし、ヌルには注意してください。

==null文字列は正常に処理されますが.equals()、null文字列から呼び出すと例外が発生します。

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

それfooString1がnullの可能性があることがわかっている場合は、読者に次のように書いてください。

System.out.print(fooString1 != null && fooString1.equals("bar"));

以下は短いですが、nullをチェックするかどうかはそれほど明確ではありません。

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

86
"=="が値を比較するように見える場合があります。 - == ない値を常に比較します!(特定の値が参照であるというだけです!)
aioobe '24

6
悲しいかな、isNullOrEmpty()の静的メソッドはなく、演算子のカスタムオーバーロードもないため、Javaのこの部分はC#やPythonよりも不格好です。また、Javaには拡張メソッドがないため、java.lang.Stringを拡張する独自のユーティリティを作成することはできません。正しい?Stringをサブクラス化し、その静的ユーティリティメソッドを追加し、常にMyStringを代わりに使用することについて何か考えはありますか?nullセーフ比較を行うための2つのパラメーターを持つ静的メソッドも、そのサブクラスに含めると便利です。
Jon Coombs、

7
Groovyでは、安全なナビゲーション演算子groovy.codehaus.org/…)を使用して、これを少し簡単にしています?.。それはnullString1?.equals(nullString2);完全にnullのステートメントに変換されます。ただし、validString?.equals(nullString);それでも例外は発生します。
チャールズウッド

5
Javaでnull可能な文字列を比較する短いメソッド:stackoverflow.com/questions/11271554/…
ヴァジム・

5
@JonCoombs Javaは、独自のメソッドのサブクラス化と作成をサポートしています。ただし、特定の理由によりfinalとマークされているクラスはほとんどありません。Stringはその1つなので、拡張できません。他のクラスを作成し、そこで2つの文字列を引数として取り、そこにロジックを実装するユーティリティクラスを作成できます。また、nullチェックには、Springやapacheなどのその他のいくつかのライブラリの優れたメソッドのコレクションがあり、それを使用できます。
パンサー

442

== オブジェクト参照を比較します。

.equals() 文字列値を比較します。

==以下の場合のように、文字列値を比較する錯覚を与えることがあります。

String a="Test";
String b="Test";
if(a==b) ===> true

これは、任意の文字列リテラルを作成すると、JVMは最初にそのリテラルを文字列プールで検索し、一致が見つかると、同じ参照が新しい文字列に与えられるためです。このため、以下が得られます。

(a == b)===> true

                       String Pool
     b -----------------> "test" <-----------------a

しかしながら、 ==次の場合失敗します。

String a="test";
String b=new String("test");
if (a==b) ===> false

この場合 new String("test")、ステートメントの新しい文字列がヒープ上に作成され、その参照がに与えられるためbb文字列プール内ではなく、ヒープ上の参照が与えられます。

さてa一方、文字列プール内の文字列を指しているbヒープ上の文字列を指しています。そのため、次のようになります。

if(a == b)===> false。

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

ながら .equals()常にStringの値を比較するため、どちらの場合もtrueになります。

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

したがって、使用すること.equals()は常に優れています。


3
.equals()は2つのインスタンスを比較しますが、equalsはそれらを比較するために実装されています。これは、toStringの出力を比較する場合としない場合があります。
ジェイコブ

3
@Jacobオブジェクトクラス.equals()メソッドは、インスタンス(参照/アドレス)を比較します。ここで、文字列クラス.equals()メソッドがオーバーライドされてコンテンツ(文字)を比較します
Satyadev

1
文字列プールとJavaヒープの違いは確かに同じではないので、指摘しておくとよいでしょう。文字列プールでは、JavaはStringオブジェクトを「キャッシュ」Stringして、不変であることで知られているようにメモリフットプリントを節約しようとします(ここでは正しく言っておきます)。また、stackoverflow.com
Roland

1
これが私が探していた答えです。
Weezy

なんて素晴らしい答えでしょう!
alwbtc


179

Javaの文字列は不変です。つまり、文字列を変更または変更しようとするたびに、新しいインスタンスが取得されます。元の文字列は変更できません。これは、これらの文字列インスタンスをキャッシュできるようにするために行われました。一般的なプログラムには多くの文字列参照が含まれており、これらのインスタンスをキャッシュすると、メモリフットプリントが減少し、プログラムのパフォーマンスが向上します。

文字列比較に==演算子を使用する場合、文字列の内容を比較するのではなく、実際にメモリアドレスを比較します。それらが両方とも等しい場合、trueとfalseを返します。一方、equals in stringは、文字列の内容を比較します。

したがって、問題は、すべての文字列がシステムにキャッシュされて==いる場合、equalsはtrueを返すのに、なぜfalseが返されるのでしょうか。まあ、これは可能です。次のような新しい文字列を作成した場合String str = new String("Testing")、キャッシュが既に同じ内容の文字列が含まれていても、キャッシュ内の新しい文字列を作成してしまいます。つまり、"MyString" == new String("MyString")常にfalseを返します。

Javaは、文字列をキャッシュの一部にするために文字列で使用できるため、"MyString" == new String("MyString").intern()trueを返す関数intern()についても話します。

注:==演算子は、2つのメモリアドレスを比較しているだけなので、equalsよりもはるかに高速ですが、コードがコード内に新しいStringインスタンスを作成していないことを確認する必要があります。そうしないと、バグが発生します。


147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

理由を理解してください。これは、==比較では参照のみが比較されるためです。のequals()メソッドは、内容を文字ごとに比較します。

new for aとを呼び出すとb、それぞれが"foo"文字列テーブルのを指す新しい参照を取得します。参照は異なりますが、内容は同じです。


128

ええ、それは悪いです...

==2つの文字列参照がまったく同じオブジェクトであることを意味します。これは、Javaがリテラルテーブル(そうする)を保持しているためだと聞いたことがあるかもしれませんが、常にそうであるとは限りません。一部の文字列は異なる方法でロードされ、他の文字列などから構築されるため、2つの同一の文字列が同じ場所に格納されていると決して想定してはなりません。

Equalsは実際の比較を行います。


124

はい、==文字列の比較には適していません(正規のオブジェクトであることがわかっている場合を除いて、実際にはすべてのオブジェクト)。 ==オブジェクト参照を比較するだけです。 .equals()等価性をテストします。文字列の場合、それらはしばしば同じですが、あなたが発見したように、それは常に保証されているわけではありません。


118

JavaにはStringプールがあり、その下でJavaがStringオブジェクトのメモリ割り当てを管理します。Javaの文字列プールを参照してください

==演算子を使用して2つのオブジェクトをチェック(比較)すると、アドレスの等価性が文字列プールと比較されます。2つのStringオブジェクトが同じアドレス参照を持っている場合はtrue、それ以外の場合はそれを返しますfalse。ただし、2つのStringオブジェクトの内容を比較する場合は、equalsメソッドを。

equals 実際にはObjectクラスのメソッドですが、それはStringクラスにオーバーライドされ、オブジェクトの内容を比較する新しい定義が与えられます。

Example:
    stringObjectOne.equals(stringObjectTwo);

しかし、それは文字列の場合を尊重することに注意してください。大文字と小文字を区別しない比較が必要な場合は、StringクラスのequalsIgnoreCaseメソッドを使用する必要があります。

どれどれ:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

7
これは大きな質問に対する遅い答えだと思います。既存の回答でまだ言及されていないことを提供してもらえますか?
Mysticial 2013

6
@Mysticial氏は追加しequalsIgnoreCaseたが、これは新人にとって有益かもしれない。
AmitG 2013

103

zacheratesからの回答に同意します。

しかし、あなたができることはintern()、非リテラル文字列を呼び出すことです。

zacheratesの例から:

// ... but they are not the same object
new String("test") == "test" ==> false 

非リテラル文字列の等価性をインターンすると、次のようになりますtrue

new String("test").intern() == "test" ==> true 

8
これは一般に良い考えではありません。インターンは比較的高価であり、(逆説的に)JVMのメモリフットプリントを>>増加<<させ、GCコストを増加させる可能性があります。ほとんどの場合、これら==は文字列比較に使用することによるパフォーマンス上の利点を上回ります。
スティーブンC

101

==Javaのオブジェクト参照を比較Stringます。これはオブジェクトの例外ではありません。

オブジェクト(を含むString)の実際の内容を比較するには、equalsメソッドを使用する必要があります

Stringを使用した2つのオブジェクトの比較==trueであることが判明した場合、それはStringオブジェクトがインターンされ、Java仮想マシンがの同じインスタンスを指す複数の参照を持っているためですStringStringとして評価Stringする==ために使用する別のオブジェクトと同じ内容を含む1つのオブジェクトを比較することを期待するべきではありませんtrue


99

.equals()クラス内のデータを比較します(関数が実装されている場合)。 ==ポインタの場所(メモリ内のオブジェクトの場所)を比較します。

==両方のオブジェクト(PRIMITIVEについて話さない)が同じオブジェクトインスタンスを指している場合、trueを返します。 .equals()2つのオブジェクトに同じデータJavaのデータが含まれている場合はtrueを返しますequals()==

それはあなたを助けるかもしれません。


95

==参照を実行します2つのオブジェクト(この場合は文字列)がメモリ内の同じオブジェクトを参照しているかどうか等価チェックをします。

このequals()メソッドは、コンテンツ状態かをチェックします、2つのオブジェクトのが同じます。

明らか==に高速ですが、2かどうかを伝えたいだけの場合は、多くの場合、誤った結果が得られる可能性があります。Stringのsが同じテキストを保持ます。

間違いなくの使用 equals()メソッドが推奨されます。

パフォーマンスについて心配する必要はありません。使用を奨励するいくつかのことString.equals()

  1. String.equals()最初に実装が参照の等価性をチェックし(を使用==)、2つの文字列が参照によって同じである場合、それ以上の計算は実行されません!
  2. 2つの文字列参照が同じでない場合、String.equals()は次に文字列の長さをチェックします。Stringクラスは文字列の長さを格納するため、これも高速な操作です。文字やコードポイントを数える必要はありません。長さが異なる場合、それ以上のチェックは行われません。これらを等しくすることはできません。
  3. これまでに取得した場合にのみ、2つの文字列の内容が実際に比較され、これは簡単な比較になります。一致しない文字が見つかった場合、すべての文字が比較されるわけではありません(2つの文字列の同じ位置にあります) )、それ以上の文字はチェックされません。

すべてのことを言い終えたら、文字列がインターンであることを保証できたequals()としても、メソッドを使用してもオーバーヘッドとは思えないかもしれませんが、間違いなく推奨される方法です。効率的な参照チェックが必要な場合は、言語仕様と実装によって同じ列挙値が同じオブジェクトになる(参照によって)ことが保証されている列挙型を使用してください。


2
Obviously == is faster-実際には.equals(String)最初のチェックの実装は==何よりも前なので、速度はほぼ同じです。
Razzle Shazl

2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl

82

私と同じように、私が最初にJavaを使い始めたとき、「==」演算子を使用して2つのStringインスタンスが等しいかどうかをテストしたかったのですが、Javaでそれを行う正しい方法ではありません。

このチュートリアルでは、Java文字列を正しく比較するためのいくつかの異なる方法を示します。まず、私がほとんどの場合に使用するアプローチから始めます。このJava文字列比較チュートリアルの最後に、Java文字列を比較するときに「==」演算子が機能しない理由についても説明します。

オプション1:equalsメソッドを使用したJava文字列の比較 ほとんどの場合(おそらく95%の場合)、次のように文字列をJava Stringクラスのequalsメソッドと比較します。

if (string1.equals(string2))

このString equalsメソッドは2つのJava文字列を調べ、それらにまったく同じ文字列が含まれている場合、それらは等しいと見なされます。

equalsメソッドを使用した簡単な文字列比較の例を見てみましょう。次のテストが実行された場合、文字が完全に同じではないため(文字の大文字と小文字が異なるため)、2つの文字列は等しいとは見なされません。

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

ただし、次の例のように、2つの文字列にまったく同じ文字列が含まれている場合、equalsメソッドはtrueを返します。

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

オプション2:equalsIgnoreCaseメソッドを使用した文字列比較

一部の文字列比較テストでは、文字列が大文字か小文字かを無視する必要があります。この大文字と小文字を区別しない方法で文字列が等しいかどうかをテストする場合は、次のように、StringクラスのequalsIgnoreCaseメソッドを使用します。

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

オプション3:compareToメソッドを使用したJava文字列の比較

また、Java文字列を比較する3番目の一般的ではない方法があり、それはStringクラスのcompareToメソッドを使用します。2つの文字列がまったく同じ場合、compareToメソッドは値0(ゼロ)を返します。この文字列比較アプローチの簡単な例を次に示します。

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

私はJavaにおけるこの等価の概念について書いていますが、Java言語には基本Java Objectクラスにequalsメソッドが含まれていることに注意することが重要です。独自のオブジェクトを作成していて、オブジェクトの2つのインスタンスが「等しい」かどうかを確認する手段を提供したい場合は、クラスのこのequalsメソッドをオーバーライド(および実装)する必要があります(Java言語が提供するのと同じ方法で) Stringのequalsメソッドにおけるこの等価/比較動作)。

この== 、. equals()、compareTo()、compare()を確認してください。


5
文字列リテラルの場合文字列string1 = "foo bar"; 文字列string2 = "foo bar"; ==演算子を直接使用してコンテンツの同等性をテストできます
JAVA

1
Googleアプリでは、スクリプト「compareTo」は使用できません。私はインスタレーションされた "equals"を試してみましたこれが機能する唯一の解決策でした...
user3887038

77

関数:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

テスト:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);

6
これは他の回答とどう違うのですか?そしてなぜそれをあなたが提案する方法で行うのか
user151019

2
@マークの違いについて質問==し、equalsすでに私はちょうど緩い方法で文字列を比較する別の方法を提供し、他のソリューションで答えた
Khaled.K

77

==2つの参照が同じオブジェクトを指してかどうオペレーターチェック。.equals()実際の文字列の内容(値)を確認します。

.equals()メソッドはクラスObject(すべてのクラスのスーパークラス)に属していることに注意してください。クラスの要件に従ってオーバーライドする必要がありますが、Stringの場合はすでに実装されており、2つのストリングの値が同じかどうかを確認します。

  • 事例1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    理由:nullなしで作成された文字列リテラルは、ヒープのpermgen領域の文字列プールに格納されます。したがって、s1とs2の両方がプール内の同じオブジェクトを指しています。

  • 事例2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    理由:newキーワードを使用してStringオブジェクトを作成すると、ヒープ上に個別のスペースが割り当てられます。


53

==オブジェクトの参照値を比較するのに対し、クラスにequals()存在するメソッドはオブジェクトjava.lang.Stringの内容をString(別のオブジェクトと)比較します。


15
うるさいことではありませんが、equals()メソッドStringは実際にはStringクラスではなく、クラスObjectです。デフォルトのequals()inではObject、内容が同じであるかどうかは比較されず、実際には、参照が同じ場合はtrueが返されます。
Jacob Schoen

1
@JacobSchoen:GrepCodeがダウンしているため、上記のリンクは機能しなくなりました。equals実装の代替方法は次のとおりです:[インラインリンク](zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/…
Amandeep Singh

50

あなたが定義すると Stringあなたはオブジェクトを定義ます。したがって、を使用する必要があります.equals()。使用するプリミティブデータ型を使用する場合==String(および任意のオブジェクト)を使用する必要があります.equals()


7
「char []」はプリミティブなデータ型ではありません!「char」の配列です。また、配列自体はプリミティブデータ型ではありません。
クリスチャン

48

equals()メソッドがに存在する場合java.lang.Objectクラス、そしてオブジェクトの状態の等価性をチェックするために期待されています!つまり、オブジェクトの内容です。一方、==オペレーターは実際のオブジェクトインスタンスが同じかどうかをチェックする必要があります。

二つの異なる参照変数を考えてみましょう、str1str2

str1 = new String("abc");
str2 = new String("abc");

あなたが使用する場合 equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

TRUE使用する場合と同じように出力が得られます==

System.out.println((str1==str2) ? "TRUE" : "FALSE");

両方が同じ文字列コンテンツを共有していても、とは2つの異なるオブジェクトを指しているFALSEため、出力としてが得られます。それは毎回新しいオブジェクトが作成されるためです。str1str2new String()


43

演算子==は常にオブジェクト参照の比較を意味しますが、コンテンツ比較ではStringクラスの.equals()メソッドがオーバーライドされます

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)

40

.equals()Objectには.equals()ブール値を返すメソッドが含まれているため、すべてのオブジェクトにメソッドがあることが保証されています。さらに定義が必要な場合は、このメソッドをオーバーライドするのがサブクラスの仕事です。これがない場合(つまりを使用==)、2つのオブジェクト間でメモリアドレスのみが等しいかどうかがチェックされます。文字列はこれをオーバーライドします.equals()メソッドをし、メモリアドレスを使用する代わりに、文字レベルで文字列を比較して等しいかどうかを返します。

重要な点は、文字列は1つの一括プールに格納されるため、文字列が作成されると、同じアドレスのプログラムに永久に格納されるということです。文字列は変更されず、不変です。これが、深刻な文字列処理を行う必要がある場合に、通常の文字列連結を使用することが悪い考えである理由です。代わりに、StringBuilder提供されているクラスを使用します。この文字列へのポインタは変更される可能性があるので、2つのポインタが同じであるかどうかを確認したい場合は、この==方法が適しています。文字列自体にはありません。


2
「文字列が作成されると、同じアドレスのプログラムに永久に保存されます」 -これは完全に間違っています。コンパイル時の定数文字列式(final String変数が関係している可能性があります)とプログラムが明示的にインターンする文字列のみが、「一括プール」と呼ばれるものに格納されます。他のすべてのStringオブジェクトは、他のタイプのオブジェクトと同様に、それらへのライブ参照がなくなると、ガベージコレクションの対象になります。また、インターンメカニズム全体が機能するためには不変性が必要ですが、それ以外の点では無関係です。
Ted Hopp、2014

文字列の比較は、equalsまたはequalsIgnoreCaseメソッドを介して行われ、文字列の内容を実際に比較します。ただし、==記号は参照値を確認するだけです。この場合、文字列プールの文字列リテラルは正常に機能します。文字列s1 = new String( "a"); 文字列s2 = new String( "a"); この場合、s1 == s2はfalseですが、s1.equals(s2)はtrueです。
Shailendra Singh

39

このcompareTo()メソッドを使用して、2つの文字列を比較することもできます。compareToの結果が0の場合、2つの文字列は等しいです。それ以外の場合、比較される文字列は等しくありません。

==参照を比較し、実際の文字列を比較しません。を使用してすべての文字列を作成した場合はnew String(somestring).intern()==演算子を使用して2つの文字列を比較できます。それ以外の場合は、equals()またはcompareToメソッドのみを使用できます。


35

Javaでは、「==」演算子を使用して2つのオブジェクトを比較すると、オブジェクトがメモリ内の同じ場所を参照しているかどうかが確認されます。つまり、2つのオブジェクト名が基本的に同じメモリロケーションへの参照であるかどうかを確認します。

Java Stringクラスは、実際にはObjectクラスのデフォルトのequals()実装をオーバーライドします。また、メソッドをオーバーライドして、メモリ内の場所ではなく、文字列の値のみをチェックします。つまり、equals()メソッドを呼び出して2つのStringオブジェクトを比較した場合、実際の文字シーケンスが等しい限り、両方のオブジェクトは等しいと見なされます。

==オペレータのチェックは2つの文字列が正確に同じオブジェクトである場合。

この.equals()メソッドは、2つの文字列が同じ値であるかどうかを確認します。


1
sがnullの場合、s.equals(s2)がクラッシュし、比較が失敗するため、それらのいずれかがnullでない限り。もちろん、これは答えと実際には矛盾しません。それは単なる警告です。
Jon Coombs

1
いいえ、クラッシュしません。NullPointerExceptionがスローされ、比較が行われません。
Bludzee 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.