次の式が false と評価されるのはなぜですか?
aStr.replace("H", "H") == "Hello"
この代替式は true と評価されますか?
aStr.replace('H', 'H') == "Hello"
JavaString
は文字列プールにリテラルをキャッシュするため、変更がないString
場合はプールから不変のインスタンスを取得し、両方がメモリ内の同じインスタンスを参照するため==
、参照時に戻りますtrue
したがって、文字列オブジェクトを比較するには、equals()
メソッド/compareTo()
メソッドを使用する必要があります
こちらもご覧ください
String
クラスのメソッドreplace(char, char)
は、一致する文字を探してスキャンします。見つからない場合は、ホストString
インスタンスをそのまま返します。当然のことながら、返された参照を演算子を使用して元の参照と比較すると、==
true が返されます。これは参照の等価性をテストしているためであり、2 つの参照は同一のものです。
ただし、元の文字列に「H」文字が含まれている場合 (ここでの例を使用)、返される文字列は元の文字列と同じではありません(文字単位で同じであっても)。これは新しく割り当てられたインスタンスであり、参照の等価性 (再び==
演算子) による比較に失敗します。String
2 つの文字列は equal であるため、返された を元の viaと比較するとObject#equals()
true が返されますが、参照の等価性によって一致しない個別のインスタンスになります。
対照的に、ターゲット文字列を正規表現String#replace(CharSequence, CharSequence)
として扱います。内部的に使用して、ターゲット パターン内の一致を指定された置換シーケンスに置き換えます。Matcher#replaceAll()
問題は、パターンが一致しないMatcher#replaceAll()
場合でも、元の文字列または新しく割り当てられたコピーを返すかどうかにかかっています。Oracle ライブラリのコードを読んだところ、一致するパターンが見つからない場合、元のに戻ります。これは、オブジェクトの場合、無害な参照を返すだけです。ここで本当の結果を報告しているかどうか疑問に思います.Matcher
CharSequence#toString()
CharSequence
String
this
提起された問題の 1 つの明白な穴は、String
参照元の元のコンテンツですaStr
。おそらく、次のような宣言を表示するつもりでした
final String aStr = "Hello";
しかし、あなたはしませんでした。aStr
両方の式の結果は、「H」文字が含まれているかどうかによって異なります。そうであると仮定すると、どちらのオーバーロードによっても文字列のインターンが行われていないと仮定して、両方の式が false になることが予想されます。String#replace()
文字列リテラルがインターンされていることはわかっていますが、両方のString#replace()
メソッドの Oracle ライブラリの実装で構築された戻り値は、新たに割り当てられたものであり、インターン プールから取得されたものではありません。
文字列比較は次を使用して行う必要があります.equals()
比較が文字列リテラル間である場合、リテラルはプールにキャッシュされ、同じ変数を参照するため、== 比較が機能する可能性があります。
equals()
値を==
比較し、参照を比較します。
String.equals () を使用して文字列を比較します。
System.out.println((aStr.replace("H","H").equals("Hello")));
trueを返します。