This question already has answers here:
What is the Java string pool and how is "s" different from new String("s")? [duplicate]
(5 answers)
Closed 8 years ago.
String str1 = new String("I love programming");
String str2 = new String("I love programming");
boolean boo = str1 == str2; // evaluates to false
String str1 = "I love programming";
String str2 = "I love programming";
boolean boo = str1 == str2; // evaluates to true
Why does first one evaluate to false and second one evaluate to true?
And here you can find more: What is the Java string pool and how is "s" different from new String("s")?
== will return true if the objects themselves have the same addresses. For space and efficiency reasons, repeated literals are optimized to use the same address. The second str1 and str2 are equal to the same address, thus == returns true.
In the first example, because you are explicitly declaring memory using the new keyword, the str1 and str2 don't have the same addresses. Thus, str1==str2 evaluates to false.
When testing equality, use the String.equals(); function instead. Thus, str1.equals(str2); //true
The equals() method compares the contents of the String and the == compares the reference in Java.
It's there in the Java Memory Model
The first equality statement returns false as your're comparing two different references of two different objects as you used the key word new which allocate memory space inside the heap in to two distinct memory addresses, the seconds, the JVM will allocate memory space once "into the stack" (from Java 7 they are in the heap as well) and the compiler optimizes memory usage by making the two variables pointing to the same memory space which it explains that the equality result is true.
Here's an interesting reading about heap, stack, ...etc. JVM Internals Blog
Cheers
Not like C. (==) compares references of java string variables. It compares two address where the strings are stored. Two compare them by values, you need to use string1.equals(string2).
Related
This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 3 years ago.
I know that there's a String pool which is supposed to keep some created strings in order to not duplicate them. So, if a user wants to create a string with the same value as another string, it won't be created once again (unless the new String() was called), it'll be a reference to the same object.
So, my question is why the result of this code is "false false"?
String a = "string1";
String b = "string1";
String c = new String("string1");
System.out.println(a==b);
System.out.println(a==c);
What interests me is WHY it's that way, not how to make Java use the pool.
The correct output for the above code is true false.
And the answer to why is string pool there is to simply optimise the memory usage. Whats the point of storing same string every time in heap memory when it can be saved once in a pool and used as long as JVM runs.
On the other hand when we are explicitly mentioning java to create an new object String s = new String("test") then it should be created as a new object and should be stored separately in heap(not in the string pool) and thereby can be updated every time when referencing this particular reference ( object s) which will not affect the string pool at all.
Other reason why string pool concept works fine for Strings is associated with the immutability of string in java.
And coming on how to decide on when to use what ?
Java recognises and stores every string literals in string pool .
If in your particular usecase there is a lot of playing involved with strings, you should be using literals carefully because it may eventually cause memory error if your code is creating massive amounts of strings in string pool. Also while working with concatenation of heavy string objects, it should be totally avoided.
String a = "Testing"
String b ="this"
String c = "I am " + a + b + "code";
Scenarios like this should be handled with stringbuffer or stringbuilder.
In all, Massive use of string pooling should be avoided. On should switch to string builder instead when using such scenarios. Things like string constants like - "HEADER" , "http://" etc that are being used multiple times are still good to be used as string literals.
This question already has answers here:
String equals and == with String concatenation [duplicate]
(4 answers)
Closed 7 years ago.
I wrote the following code:
String s="Rahul";
String s2=s.concat(" Shukla");
String s3="Rahul Shukla";
System.out.println(s2==s3);
I was expecting true as the output of s2==s3, but it becomes false. As I think s2 and s3 are pointing to the same object in the string constant pool, so s2==s3 should evaluate to true. Can anyone please tell me what is really going on here?
First of all, unless you care about JVM internals and unreliable "guarantees", don't use ==. Just don't.
Secondly, when calling concat with " Shukla", the result is not in the constant pool. Rahul and Shulka are, but their concatenation is a new String on the heap:
Strings computed by concatenation at run time are newly created and therefore distinct.
+ as an operator is different since it's not a method call, in the case where both of its operands are known to be constant (by being a string literal):
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Literal strings within the same class (§8 (Classes)) in the same package (§7 (Packages)) represent references to the same String object (§4.3.1).
All quotes are from the JLS, Version 8, section 10.3.5.
If you did create every string using new String(somestring).intern() then you can use the == operator to compare two strings, otherwise equals() or compareTo methods can only be used. equals() method is present in the java.lang.Object class and it is expected to check for the equivalence of the state of objects.
Check this link : How do I compare strings in Java?
Since String is immutable concat() method will create new string object. but s3 will refer to an object which is in string pool. So s2==s3 it will return false
The s3 variable is created in the pool and s2 in the heap since == compare the reference the are not equal which gave you false.
String s3="Rahul Shukla";
Is creatd in the poot as s3 value can be determined at compiletime
String s2=s.concat(" Shukla");
is created in the heap because if you see the source code of concat() it returns new String()
Interestingly, the specification of concat has changed between Java 7 and Java 8.
The Java 7 Specification says:
If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created...
Whereas the Java 8 Specification says:
If the length of the argument string is 0, then this String object is returned. Otherwise, a String object is returned that represents a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.
However, the implementation doesn't seem to have changed. Here is the code.
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
This means that if you use == to compare the result of s.concat(" Shukla") with s3 you will get false, but this is not strictly speaking guaranteed by the specification.
However, as others have pointed out, you do not need to care about this. You should just compare strings using .equals and forget about the details.
I have some questions about string comparison.I couln't find any answers concerning replace and substring methods in particular.So here is the code
public static void main(String args[]) {
if ("hello".substring(0) == "hello")
System.out.println("statement 1 is true");
if ("hello".substring(1) == "ello")
System.out.println("statement 2 is true");
if ("hello".replace('l', 'l') == "hello")
System.out.println("statement 3 is true");
if ("hello".replace('h', 'H') == "Hello")
System.out.println("statement 4 is true");
if ("hello".replace('h', 'H') == "hello".replace('h', 'H'))
System.out.println("statement 5 is true");
}
The output is:
statement 1 is true
statement 3 is true
Does the substring method create a new String().If so why is statement one true,yet 2 is not?Same question goes about statement 3 and 4.Thank you.
I assume you are aware of how string comparison works. So i'll try to explain what is happening.
Strings in java are immutable objects, so once created you can't change them.
To reduce overhead in creating the "same" string object over and over again, there is a pool of already used/created strings.
Now when you now compare if two string objects are the same it compares whether the objects themselves are the same. if you do "hello".substr(0) it will "create" a string object with "hello" in it. Since "hello" was already used, the string object containing "hello" is already in the string object pool. And if you now again "create" the string object "hello" to compare with, it will return the same object from the pool.
The same is happening with the "hello".replace("l","l") it will return the same "hello" string object like above.
But you can not rely on that, because the string-pool can get emptied at any time.
Further reading for "internalling strings" http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#intern()
BUT, if your question is about how to compare string themselves not the objects containing you strings, you should really use "hello".equals("hello") because then it will compare the real content. (As mentioned above)
If you compare strings with .equals() (to test value equality) rather than == (which tests referential equality), your program will output different results.
You should not be comparing strings like that in java. == is comparing the string references instead of the strings itself. Use .equals() method already defined for quality comparison of strings.
str1.equals("Hello");
The substring() method (which was changed in Java 7), will always return a new object. The only exception to this is if it is to return the whole string (substring(0)). Then, it will return it from the pool and the equality expression (==) will evaluate to true. This is the reason why statement 1 is true, but statement 2 false.
An example.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
I am working with Java code in JSP and I am trying to compare strings and I am having problem with that.
I have declared two strings
s1 = "din";
s2 = "din";
However, the if (s1 == s2) never executes. Can someone help me?
The operator == for Strings compares for reference equality, not value equality.
Try calling equals instead of using ==:
if (s1.equals(s2)) { ... }
When comparing strings you should always use the equals method, not ==:
if(str1.equals(str2))
...would be the correct way to do things.
Where confusion arises is cases like the following:
String str1 = "hello";
String str2 = "hello";
System.out.println(str1==str2);
The above will actually print out true. However, save for academic purposes like the above, you shouldn't ever use it. If you're using == you're checking if the values are physically the same object on the heap. If you're using .equals() you're checking that they're meaningfully equal, even if they're actually two separate objects.
Sometimes, especially where literals are involved such as above (or when you manually call the intern() method) Java will automatically make two separate string objects point to the same object for performance reasons. However, there's no logical guarantee this will happen (unless you want to bother yourself with explicit details of the JLS, and even then it's only guaranteed sometimes) and most of the time it won't. Take the following for example:
String str1 = "hello";
String str2 = "he";
str2 += "llo";
System.out.println(str1 == str2);
Now it prints false, because despite being meaningfully equal we haven't hit the same optimisation that Java was providing previously.
In both cases above, using ,equals() would return true.
You use 'equals' when you compare strings.
if(s1.equals(s2)) { true }
What are you trying to achieve?
Compare String's or their values?
If you are expecting that your (if) condition should return true then use
s1.equals(s2);
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to know how many objects will be created with the following code?
I have following lines of code in a program
String str1 = "abc";
String str2 = str1;
String str3 = "abc";
I want to know how many objects are created when above 3 lines of code is executed.
All the three references refer to the same interned String object.
2, 1 string object and the string contains 1 character array.
only one object is created. The rest(str2,str3) are referred to internal string pool.
It can create 0 or 1 object.
If there is already an interned String object with value "abc" no objects are created and if its not present, it gets created.
3 objects, but they all use the same interned string (i.e. the string only exists once in the running JVM).