Comparing two strings with equal(==) operator [duplicate] - java

This question already has answers here:
String comparison and String interning in Java
(3 answers)
Closed 9 years ago.
I was kind of telling some one that , we must use String.equals method to compare two strings values, we can not simply use == operator in java to compare Strings, and told him that == will return false as it doesn't compare the string value but String object reference value.
I have written this example to show him, but for my surprise it always prints true for == operator..
here is the code
public void exampleFunc1(){
String string1 = "ABC";
String string2 = "ABC";
if(string1 == string2)
System.out.println("true");
else{
System.out.println("false");
}
System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
System.out.println(" Are they equal "+(string1.equals(string2)));
}
Output:-
Are they equal true
Are they equal true
So question here is in what circumstances == operator on objects can print true, except that both objects are same instance?

String is one of a few special cases.
Class String keeps a special pool of "interned" Strings. Method myString.intern() looks up myString in this pool. If another String with the same contents already exists in the pool, a pointer to it is returned. If not, myString is added (and a pointer returned).
When you say myString= myString.intern() ;, you are effectively making myString refer to a shared copy or its underlying String available for future sharing (and no duplication). Most library methods creating Strings are subject to this, particularly String literals.
Other cases of "interning" occur with wrapper types Integer, Long, etc. They don't have constructors, but static methods valueOf() that return pre-built, shared objects when they can (usually the 256 values closest to zero), and new objects when they can not. The later is not much problematic because these types are more lightweight than Strings. Long, for example, has a payload of just 8 bytes. String contains a char[] that even empty is 16 bytes or so.
To answer your question, you can not count on any "interning" mechanisms. They have changed in the past, and they could change in the future (or even from one JVM to another), making your code unusable. Always use equals.

You should use
String string1 = new String("ABC");
String string2 = new String("ABC");
Then everything would be correct like what you think,
In this case, "ABC" is just a reference to a const string.

The compiler may be optimizing the assignments and only creating one String object. If you use the explicit String constructor, the == operation should behave as expected.

Related

String array vs String split array [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
String s = "Hi Hello Hola";
String[] d = s.split(" ");
System.out.println(d[0] == "Hi"); // prints false
String[] e = { "Hi", "Hello", "Hola" };
System.out.println(e[0] == "Hi"); // prints true
Here we have an array d with the values Hi, Hello, and Hola. We have another array e with the same set of values.
But why does this comparison behaves differently? Why does it print false and then true?
I expected false for both! As we are comparing a string literal value with the string value by using ==.
Why is this difference?
Update Here my question is not about the comparison of String values. I'm aware of the differences between == which compares the references and equals() which compares the content of the string.
From the answers, i understand that in the second case, Hi value is interned and refers to the same object. But in the other case, split creates new values without checking the literal pool. Is it right? Am i missing anything?
The reason beeing is the compiler. At compile time the compiler does notice that the literal Hi exists twice in the code and does intern this string for your specific class.
After compilation both of your interned strings Hi are pointing to the same reference of Hi. That´s the reason why the second print results in true.
The split doesn´t know it´s result and creates new references for the corresponding Strings. That´s the reson why Hi from the split and the literal Hi are not using the same reference.
This is happening because internally when split(Pattern) matches the pattern, and finds the matching char sequences, then it uses String.substring(start,end) for creating a new String object. That is why results returned by split are false. This is code snippet from java.util.regex.Pattern.split(CharSequence input, int limit) class.
String match = input.subSequence(index, m.start()).toString();
Here the input is instance of the String class, which is passed to the Pattern.split(CharSequence, int) method.
Reference: Pattern
Trying to use '==' on strings is very unpredictable. The first time you type in "Hi" as a literal, it is saved into memory. When you then assign it into the array 'e', it uses that same saved literal for storing it in the array. When you then check to see if they are equal, it resolves as true.
I highly recommend not using '==' and use one of the many methods that are provided in Java.
System.out.println("Hi".equals(d[0]));
System.out.println("Hi".equals(e[0]));
or...
System.out.println(("Hi".compareTo(d[0]) == 0));
System.out.println(("Hi".compareTo(e[0]) == 0));

Java test String Handling [duplicate]

This question already has answers here:
Comparing strings with == which are declared final in Java
(6 answers)
Closed 7 years ago.
I was doing some java tests to practice and I came across a question that I don't understand. I created a small program to test it:
The question was to say what would be the output of System.out.println(ab==abc);
I answered 'true' thinking that String literals are not objects, so the can be seen as a kind of primitive type so the comparation == would compare the values and nothing to do with references. But actually the answer in "false";
Then I did this test and I even print the outputs and as you can see ab and abc are exactly the same, however the comparation is returning false , but if I do the comparation directly without doing any concatenation (as I did at the end of the program) the comparation is returning true. So it seems clear the reason has to be with the concatenation, I know that Strings are inmutable so when concatenating then we are getting another String literal with exactly same value.
Can someone please explain me who't going on here?
For those telling me that String literals are objects, why then this code returns true?
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output true
Of course I would understand that this code
String o=new String("meowdeal");
String p=new String("meowdeal");
System.out.println(o==p);
returns false because in that case they are really objects but not when they are String literal, am I right?
Thank you for your time
public static void main(String ads[] ){
String a="meow";
String ab=a+"deal";
String abc="meowdeal";
System.out.println(a);
System.out.println(ab);
System.out.println(abc);
System.out.println(ab == abc);
//output
//meow
//meowdeal
//meowdeal
//false
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output
//true
}
ab and abc are objects so .equals() is used to see if they have the same contents and == is used to see if they are the same object.
The last test is only true due to a compile optimization known as string interning
(Your second comment below is correct)
In Java you should compare Strings with .equals(String s) because the '==' returns only true if it's the exact same String in the memory and doesn't compare if the content is the same. In your first example you've got two different strings in your memory. In the second, java saw, that these would be the same and allocated only space for one string and your p and o are only a reference to the same object.
String literals are Objects. User equals method instead of == operator.
Just to explain what happen here,
String p="meowdeal"; //creates "meowdeal" in heap
String o="meowdeal"; // o also refer to same object in heap.
This is called pooling of String. Since both refer to same memory location == operator returns true.

Can anyone please explain why output of the following is such? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
String str1 = "abc:5";
String str2 = "abc:" + str1.length();
String str3 = "abc:" + 5;
System.out.println(str1==str2);
System.out.println(str1==str3);
Output of the program is :
false
true
But I don't understand why?
== operator will compare reference only
.equals() will compare the values.
in your case
str1==str2 // compares the two references, which are different.
had it been, str1.equals(str2), it would have compared the values, which will return true
The “==” operator
In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.The “==” operator compares the objects’ location(s) in memory
The “equals” method
The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory.
Here str1 = "abc:5"; is located in constant pool of string and str2 is concatenated with 2 different object with new operator. So both str1 and str2 are referring to different object. That's the reason it is showing false.
The == operator is used for only reference variables in java. For example if you are comparing characters a1 and a2 you can use the == operator because the char type is highlighted in most IDEs in Java. To check if two Strings are equal to each other you can use .equals()or .equalsIgnoreCase() to compare the Strings. This is because Strings are objects, not primitives, and require their own method in the class to test if Strings are the same.
For the first System.out.println(); statement, you would use System.out.println(str1.equals(str2)); or System.out.println(str1.equalsIgnoreCase(str2));.
For the second System.out.println(); statement, you would use System.out.println(str1.equals(str3)); or System.out.println(str1.equalsIgnoreCase(str3));.

Is it more proper to use the equivalent operator or the equals() method to compare the contents of Strings? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I'm reading about the notion of interned strings:
String s1 = "Hi";
String s2 = "Hi";
String s3 = new String("Hi");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1.equals(s3)); //true
String is an object in Java, but the compiler allows us to use a literal for assigning to a String reference variable, instead of requiring us to use the new operator, because of the ubiquity of strings in programming. The use of the literal for assignments creates an interned string. All interned strings with the same literal point to the same space in memory, thus the equivalent operator is permitted.
It got me wondering, however: would it not be more proper to use the equals() method to compare two string reference variables, given that in Java strings are objects (and not arrays like in other languages) and the contents of objects should be compared using equals(), as the == operator in regards to objects only tells us that they point to the same spot in memory?
Or is it not more proper because the very concept of interned strings makes it clear that one String can only be equivalent (==) to another string if they share the same literal?
If it is more proper, do people commonly use the equals() method regardless, or is it considered overkill?
Yes equals is the method used to compare the contents of string objects. Using == we can only compare whether the two references point to the same memory location or not. But using equals you can check whether two references hold the same string content, be them at the same memory location or not. Logically speaking, when you are trying to compare two strings, you must be looking for comparing the contents of those strings and not the memory locations of them.
As a practice or almost everywhere string equals method is used for string comparision and not ==

== operator does not compare references for String [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
String comparison and String interning in Java
I understand how String equals() method works but was surprised by some results I had with the String == operator.
I would have expected == to compare references as it does for other objects.
However distinct String objects (with the same content) == returns true and furthermore even for a Static String object (with the same content) which is obviously not the same memory address.
I guess == has been defined the same as equals to prevent its misuse
No, == does just compare references. However, I suspect you've been fooled by compile-time constants being interned - so two literals end up refererring to the same string object. For example:
String x = "xyz";
String y = "xyz";
System.out.println(x == y); // Guaranteed to print true
StringBuilder builder = new StringBuilder();
String z = builder.append("x").append("yz").toString();
System.out.printn(x == z); // Will print false
From section 3.10.5 of the Java language specification:
String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.
The reason it returns the same is because of memory optimizations (that aren't always guaranteed to occur) strings with the same content will point to the same memory area to save space. In the case of static objects they will always point to the same thing (as there is only one of it because of the static keyword). Again don't rely on the above and use Equals() instead.
One thing I should point out from Jon Skeet is that it is always guaranteed for compile time constants. But again just use equals() as it is clearer to read.
It is due to string intern pooling
See
whats-the-difference-between-equals-and
The == operator does always compares references in Java and never contents. What can happen is that once you declare a string literal, this object is sent to the JVM's string pool and if you reuse the same literal the same object is going to be placed in there. A simple test for this behavior can be seen in the following code snippet:
String a = "a string";
String b = "a string";
System.out.println( a == b ); // will print true
String c = "other string";
String d = new String( "other string" );
System.out.println( c == d ); // will print false
The second case prints false because the variable d was initialized with a directly created String object and not a literal, so it will not go to the String pool.
The string pool is not part of the java specification and trusting on it's behavior is not advised. You should always use equals to compare objects.
I guess == has been defined the same as equals to prevent its misuse
Wrong. What is happening here is that when the compiler sees that you are using the same string in two different places it only stores it in the program's data section once. Read in a string or create it from smaller strings and then compare them.
Edit: Note that when I say "same string" above, I'm referring only to string literals, which the compiler knows at runtime.

Categories