How does the comparison in Strings work? [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
String comparison - Android [duplicate]
(17 answers)
Closed 8 years ago.
When I compare ("String"=="String"), what exactly I am comparing, the two objects or two references?
Please explain the output of following code snippets:
1) System.out.println("String".toString()=="String"); // output is true
2) System.out.println("String".trim()=="String"); // output is true
3) System.out.println("String ".trim()=="String"); // output is false
According to statement 1 and 2, the output of 3rd statement should also be true. Please explain what is going on here.

From my previous answer, You have to remember, == compares the object references, not the content.

trim() returns a copy of this string with leading and trailing white space removed, or this string if it has no leading or trailing white space.
in the first case the answer is true no surprise about that because the references are equal
in the second case there are no leading or trailing spaces so trim returns the same string again the references are equal
in the last case trim returns a copy as the string has a trailing white space which results in a different reference so your comparison will be false.

In java you should never compare strings with the equality operator ==, since that operator compares references rather than contents. The compiler is smart enough to reuse one reference for all equal literals found in the code (so the four occurrences of String in 1) and 2) are probably the same instance). However in 3) you have two different literals and there is no guarantee that "String ".trim() will be represented by the same instances as the literals.
See also: https://stackoverflow.com/a/513839/55787
Use .equals() instead.

== compares whether the two String references you are comparing point to same String instance or not.
To answer your question you need to check the source code of methods in String class
public String trim() {
int len = count;
int st = 0;
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[off + st] <= ' ')) {
st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}
public String toString() {
return this;
}
As you can see it return this in case of trim if there is nothing to trim which is why you get true. Also toString simply returns this.

you have to use the method
equals()
to compare Strings. Instead with == you are comparing
references.

== compares memory location . In the first case , the toString method returns the same object ,and since both "String" objects being compared point to the same object on the constant pool, the result is true. In the second case, the trim method does no modification to the String so it returns the same object, with the same result. The third case and the second call to trim returns a different object, not located on the constant pool

Related

What will be output and explanation? [duplicate]

This question already has answers here:
Getting strange output when printing result of a string comparison
(3 answers)
Closed 3 years ago.
Below code return boolean false value. Any explanation for this ?
String str = "Bee";
String str2 = "Bee";
System.out.println("==" + str == str2);
Actual Result : false
Use equals to compare string, it will return true for this case.
The == operator compares that the Strings are exactly the same Object.
This might theoretically happen in case of internalized strings, but you cannot rely on this. For your case, comparing String values, use str.equals(str2).
str and str2 are both assigned the same String instance, since String literals are automatically stored in the String pool. Therefore str == str2 is true.
However, you are printing the expression "==" + str == str2. That expression is evaluated from left to right, so first "==" + str is evaluated, and results with the String "==Bee". Then the == operator is applied to "==Bee" and "Bee", which returns false.
If you change the statement to:
System.out.println("==" + (str == str2));
you'll get true, since now the comparison will take place prior to the String concatenation.

Why trim() give me String Constant Pool reference?

I am exploring String Constant Pool and Heap memory.
if("String".trim() == "String")
System.out.println("Equal");
else
System.out.println("Not Equal");
Output
Equal
And If I add a space in the String before trim, It will give Not Equal output
if("String ".trim() == "String")
System.out.println("Equal");
else
System.out.println("Not Equal");
Output
Not Equal
Can you explain me above scenario?
And How can I see Heap Memory and String Constant Pool?
The (Java 8) javadocs for String.trim() state:
Returns: A string whose value is this string, with any leading and trailing white space removed, or this string if it has no leading or trailing white space.
Since "String" has no leading or trailing spaces, trim() is returning the "String" object.
On the other hand "String " has trailing spaces, so a different String object is returned1.
BTW: It is not called the "string constant pool". All strings are constant (immutable). You might be be talking about all strings that are the result of the evaluation of a compile time constant expression. However, the string pool can also contain strings that were added by a String.intern() call on a dynamically created string. The correct term is the "string pool".
1 - It happens that this object is a different object to the one that represents the "String". However, a careful reading of the javadoc will reveal that the spec does not require this to be the case. In a different (hypothetical) version of Java, the trim() method could return the "String" object and still conform to the spec.
trim() method can return the same instance or a totally new created string object, you can verify that in the source code of the method:
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
so it will depends wether this condition meet or not
((st > 0) || (len < value.length))
now when you do: "String".trim() == "String" the condition doesnt meet so you will compare the reference of the literal "String"
on the option left, a new object is created and the comparison using == returns false....
The second example shows "Not Equal" because,
The method trim() returns a copy of this string with leading and trailing white space removed, or this string if it has no leading or trailing white space.
The word copy is important.
Strings are objects, so comparing Strings with == is not the right choice. Trim returns a String, then you need to compare it to another String using equals, even if the string is not wrapped into a variable. Try using:
System.out.println(" this is a string ".trim());
String test = " this is a string ";
System.out.println(test.trim());
both are going to give the same answer: "this is a string"
I your case you should use:
"string".trim().equals("string")
which will give you the right answer.

Strange Behavior of Empty String in JAVA [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I am working on a Existing code and i found a Strange Behavior while checking a String is null or Empty. The existing code :
System.out.println("Length: " + value.length());
if (value != null && value != "") {
//code
}
Output:
Length: 0
But the if statement becomes true and its executing the code.
When i replaced the if statement with this one:
if (value != null && value.length() > 0) {
//code
}
It works perfectly. Any idea why the previous one failed and Why value != "" returns true?
Try to use equals method like this:
if (value != null && !"".equals(value)) {
Strings are not compared like this:
value != ""
Use equals:
!"".equals(value)
or isEmpty:
!value.isEmpty()
Because String is immutable
You should compare with value.isEmpty(). According to the source code, it will also compare the length.
What you are doing with != is comparing references, not equality.
When using == you are comparing the references which are not equal, that's why the expression evaluates to true.
You can use StringUtils.isNotEmpty
if (StringUtils.isNotEmpty(value)) {
...
}
true - if the String is not empty and not null
Reference
String is an Object in java, so you can't use == and != with it, because == and != comparing references, which is not equal. Use "".equals(value)
This is because you might have created value variable using new operator:
String value = new String();
So now if you use following :
System.out.println("Length: " + value.length());
if (value != null && value != "") {
System.out.println("hi")
}
It will print hi as value is from heap and literal "" is from string pool and you are making reference comparison. Use equals method instead .
value != ""
check for reference equality not the value equality.
if value is created like this:
String value=new String("");
then there is a high chance that the condition will fail.
For example if you have another String value2
String value2=new String("");
then
value==value2 // is false.
Have a look at this How do I compare strings in Java?
Your best bet is to use value != null && !value.isEmpty(), although you can ace this with the Yoda Expression
"".equals(value)
which saves you typing out the explicit check for null.
You can't use == since that would compare the object reference values (which might be different even if the string looks the same), not the string contents.

Checking a number in String Variable [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I am getting a value as 9999912499 from the database.
I have separated it in two parts 99999 and 12499 using substring.
Now I want to check whether if the 1st string is equal to 99999 then i do some processing otherwise something other processing.
But controls never gets in to the if loop
Following is a snapshot:
String strPscId = Long.toString(pscID);
String convPscID = strPscId.substring(5, strPscId.length());
String checkNine = strPscId.substring(0,5);
BigDecimal jpaIdObj = jeuParam.getJpaIdObj();
Long mod_id = modele.getModId();
log.info("outstrPscId == " +strPscId);
log.info("outconvPscID == " +convPscID);
log.info("outcheckNine == " +checkNine);
log.info("outjpaIdObj == " +jpaIdObj);
log.info("outmod_id == " +mod_id);
if(checkNine == "99999") { <method-call> }
else { <another - method - call> }
For some reason, the people that make java decided that == shouldn't be used to compare Strings, so you have to use
checkNine.equals("99999");
Look at the following code:
String str1 = "abc";
String str2 = str1;
In the first line, a new string is created and stored in your computer's memory. str1 itself is not that string, but a reference to that string. In the second line, str2 is set to equal str1. str2 is, like str1, only a reference to a place in memory. However, rather than creating an entirely new string, str2 is a reference to the same place in memory that str1 is a reference to. == checks if the references are the same, but .equals() checks if the each character in a string is the same as the corresponding character in the other string.
boolean bool1 = (str1 == str2);
boolean bool2 = str1.equals(str2);
If this code were added to the code above that, both bool1 and bool2 would be true.
String str1 = "abc";
String str2 = new String(str1);
boolean bool1 = (str1 == str2);
boolean bool2 = str1.equals(str2);
In this case bool2 is still true, but bool1 is false. This is because str2 isn't set to equal str1, so it isn't a reference to the same place in memory that str1 is a reference to. Instead, new String(str1) creates an entirely new string that has the value of str1. str1 and str2 are references to two different places in memory. They contain the same value, but are fundamentally different in that they are stored in two different places, and therefore are two different things.
If I replaced new String(str1) with "abc" or str1, bool1 would be true, because without the key word new, the JVM only creates a new string to store in memory if absolutely necessary. new forces the JVM to create an entirely new string, whether or not any place in memory already has the same value as the new string being created.
.equals() is slow but generally more useful than ==, which is far faster but often does not always give the desired result. There are many times when == can be used with the same result as .equals(), but it can be difficult to tell when those times are. Unless you a knowledgeable programmer making something where speed is important, I would suggest that you always use .equals().
You need use equals method, rather than == to compare strings.
Change from
if(checkNine == "99999")
to
if(checkNine.equals("99999"))
The == operator is used to compare the content of two variables. This works as expected when using primitive types (or even wrapper classes because of auto-boxing). However, when we are using == with a reference to an object (e.g., checkNine), the content is the reference to the object but not the value of the object. This is where equals() method is used.
if("99999".equals(checkNine)){
<method-call>
}
else {
<another - method - call>
}
if(checkNine.equals( "99999")) {
<method-call>
}
else {
<another - method - call>
}
if (strPscId.startsWith("99999"))
{
bla bla
}
else
{
sth else than bla bla
}

what happens when converting char to string? (Java) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I compare strings in Java?
I'm using String.valueOf to convert char to string. But the return value seems not exactly same as a string of the same letter. Codes below:
String myString = "s";
char myChar = 's';//both string and char are assigned as letter 's'
String stringFromChar = String.valueOf(myChar);
if (myString == stringFromChar) {
out.println("equal");
} else {
out.println("not equal");
}
Every time it prints not equal. Please help, thanks! :)
== compare the reference, not the actual value. You must use equals to compare the value.
Read this article if you don't understand it's clear and simple.
NEVER DO THIS AGAIN!!! PROMISE ME!!! =P
When comparing strings always, always, always use the equals method. See Below!
String myString = "s";
char myChar = 's';//both string and char are assigned as letter 's'
String stringFromChar = String.valueOf(myChar);
if (myString.equals(stringFromChar)) {
System.out.println("equal");
} else {
System.out.println("not equal");
}
}
what happens when converting char to string?
Well, you are using the String.valueOf(char) method, whose javadoc does not say how it does the conversion. But the behaviour you are seeing strongly suggests that the JVM you are using creates a new String object each time you call the method.
But you should depend on this happening.
The bottom line is that you should always use the equals method to compare strings. Comparing strings with == will often give you false negatives ... depending on how the strings were created / obtained. You've just been bitten by that. Learn.
Reference:
How do I compare strings in Java?

Categories

Resources