Why does the Java String # replace () method work differently with characters and strings?

Why the following expression evaluates to false

aStr.replace("H", "H") == "Hello" 

while is this alternative expression evaluating to true?

 aStr.replace('H', 'H') == "Hello" 
+4
source share
4 answers

Java caches the String literal in the String pool, so if there are no changes to String , it will require an immutable instance from the pool and so that both refer to the same instance in memory and thus == when returning the link true

So, to compare String Object, you have to use equals() method / compareTo()


Also see

+4
source

String comparisons should be done using .equals()

If the comparison is performed between string literals, then the comparison may work because the literals are cached in the pool and refer to the same variable.

equals() compares the values, == compares the link.

+2
source

The String class replace(char, char) method scans for a matching character. If it does not find it, it returns an instance of the String host as is. Naturally, comparing the returned link to the original link using the == operator returns true, since this is a test reference equality and the two links are the same.

If, however, the original string contains the character "H" - using your example here - then the returned string will not be the same as the original string (although it will be the same for each character); it will be a freshly distributed instance that could not be compared by reference equality (again, the == operator). Comparing the returned String with the original via Object#equals() will return true, since the two strings are equivalent, but they will be different instances that cannot match using reference equality.

In contrast, String#replace(CharSequence, CharSequence) treats the target string as a regular expression; it uses Matcher#replaceAll() inside to replace matches in the target template with the following replacement sequence.

Now the question is whether the original string or the just selected copy of Matcher#replaceAll() will return, even if the template does not match. By reading the code in the Oracle library, if Matcher does not find the corresponding template, it returns CharSequence#toString() in the original CharSequence , which for String objects simply returns this link is not damaged. This makes me wonder if you are reporting the true result here.

One obvious hole in the question aStr is the original String content referenced by aStr . You probably wanted to show an ad like

 final String aStr = "Hello"; 

but you didn’t. The result of both expressions should depend on whether aStr contains the character β€œH” or not. Assuming this is the case, I expect both expressions to be false, assuming no string interning plays in one of the String#replace() overloads. We know that string literals are interned, but the return values ​​that we see are built in the Oracle library implementation of both String#replace() methods, have just been allocated and not extracted from the internal pool.

+2
source

use String.equals () to compare strings.

  System.out.println((aStr.replace("H","H").equals("Hello"))); 

will return true .

0
source

Source: https://habr.com/ru/post/1436882/


All Articles