The difference between the following two statements:
String s = "Hello";
String s = new String("Hello');
In the first statement, assignment operator-is used to assign the string literal to the String variable s. In this case; JVM first of all checks whether the same object is already available in the string constant pool. If it is available, then it creates another reference to it. If the same object is not available, then it creates another object with the content "Hello" and stores it into the string constant pool.
In the second statement, new operator is used to create the string object. In this case, JVM always creates a new object without looking in the string constant pool.
The doubt I am having from the code which I have provided below is the output of statement
System.out.println(a.hashCode() + " " + b.hashCode());
Here both the object should have different memory location according to the rules, but hashcode for both of them is showing true
import java.util.HashMap;
import java.util.Map;
class TestStringEquality
{
public static void main (String[] args)
{
String a = new String("abcd");
String b = new String("abcd");
System.out.println(a == b);
System.out.println(a.hashCode() + " " + b.hashCode());
System.out.println(a.equals(b));
Map<String, String> map = new HashMap<>();
map.put(new String("abcd"), "abcd");
map.put(new String("abcd"), "wxyz");
System.out.println(map);
}
}
The output what i am getting is as follows:
false
2987074 2987074
true
{abcd=wxyz}
According to the API sheet at https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode--
the formula used in hashcode of a String is dependent on the length and content of the String, not the memory location. Therefore two identical Strings with different memory locations should give the same hashcode.
Java has one concept named String Pool. Every string has used in the program will be stored in the pool as the cache mechanism.
For example below code:
String a = "StackOverFlow"; // Java will push StackOverFlow into string pool
String b = "StackOverFlow"; // Java will get address of "StackOverFlow" object in string pool and assigned to b.
In Java, programmers don’t have to directly work with pointers. However, pointers still are here. When using the operator "==", primitive data-type variables like int, short … will compare by their values. But in String, Java will compare by their addresses.
That is the reason the following line will return true:
System.out.println(a == b); // true
However, when you call new String(...), Java will create a new string object. It doesn’t look into String Pool to check that string’s value has stored in String Pool or not. That is the reason two variables have the same value, they are still different in address so "==" operator will return false.
String a = "StackOverFlow";
String b = new String("StackOverFlow"); // new string object. not use old one in String Pool.
System.out.println(a == b); // False. because they have different addresses.
Because of String Pool mechanism, we must use equals method when compare two objects. By doing this, we don’t need to care how that String object is built. So following code always return true:
String a = "StackOverFlow";
String b = "StackOverFlow"; // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.equals(b)); // true
System.out.println(a.equals(b)); // true
System.out.println(a.equals(c)); // true
About hashcode, Java will use a hash function to calculate the value from the string's characters. That way no matter how a string is built, if 2 strings are equal in value, they will have the same hash code.
String a = "StackOverFlow";
String b = "StackOverFlow"; // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.hashCode() == b.HashCode()); // true
System.out.println(a.hashCode() == c.HashCode()); // true
Based on the discussion, we can come to the following conclusion. If 2 strings have the same hash code, we cannot affirm operator "==" returns true. Because they might be the same value, but they are different objects on heap memory.
But the vice versa condition is correct. If 2 strings point to the same address, they will have the same value hence the same hash code.
Interesting question: If two strings have equal hash codes, can we assume those 2 strings will equal?
hashCode() implementaiton of "Object" class returns underlying memory location.
hashCode() implementaiton of "String" overrides hashCode() in Object. Returns a hash code for this string. The hash code for a String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
Also, this makes programmers life easier. For example, we can query a Map using hard coded string key, instead of keeping the original key object with us.
I think you are getting confused between normal heap memory and string constant pool. When you check for equals , JVM is fetching you the object stored in normal heap memory which is one and the same . They are different only in string constant pool. That's why '==' returns false as locations are different in string constant pool because the copies have different references but equals returns true since both are of same type and hold similar string.
this string equality you can use hashcode method.
but, for better performance use
String firstString = "string1";
String secondString = "String1";
println(" it will return boolean " + firstString.equal(secondString ) + " "); //false
println(" it will return boolean " + firstString.equalIgnoreCase(secondString ) + " "); //true
Related
The commonly agreed answer to this interview question is that two objects are created by the code. But I don't think so; I wrote some code to confirm.
public class StringTest {
public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
String s3 = new String("a");
System.out.println("s1: "+s1.hashCode());
System.out.println("s2: "+s2.hashCode());
System.out.println("s3: "+s3.hashCode());
}
}
The output is:
Does this mean that only one object was created?
Reaffirm: My question is how many object was created by the following code:
String s = new String("xyz")
Instead of the StringTest code.
Inspired by #Don Branson, I debugged the below code:
public class test {
public static void main(String[] args) {
String s = new String("abc");
}
}
And the result is:
The id of s is 84, and the id of "abc" is 82. What exactly does this mean?
THERE ARE ERRORS BELOW DEPENDING ON THE JVM/JRE THAT YOU USE. IT IS BETTER TO NOT WORRY ABOUT THINGS LIKE THIS ANYWAYS. SEE COMMENTS SECTION FOR ANY CORRECTIONS/CONCERNS.
First, this question really asks about this addressed here:
Is String Literal Pool a collection of references to the String Object, Or a collection of Objects
So, that is a guide for everyone on this matter.
...
Given this line of code: String s = new String(“xyz”)
There are two ways of looking at this:
(1) What happens when the line of code executes -- the literal moment it runs in the program?
(2) What is the net effect of how many Objects are created by the statement?
Answer:
1) After this executes, one additional object is created.
a) The "xyz" String is created and interned when the JVM loads the class that this line of code is contained in.
If an "xyz" is already in the intern pool from some other code, then the literal might produce no new String object.
b) When new String s is created, the internal char[] is a copy of the interned"xyz" string.
c) That means, when the line executes, there is only one additional object created.
The fact is the "xyz" object will have been created as soon as the class loaded and before this code section was ever run.
...next scenario ...
2) There are three objects created by the code (including the interned "a")
String s1 = "a";
String s2 = "a";
String s3 = new String("a");
a) s1 and s2 are just referenced,not objects, and they point to the same String in memory.
b) The "a" is interned and is a compound object: one char[] object and the String object itself. It consisting of two objects in memory.
c) s3, new String("a") produces one more object. The new String("a") does not copy the char[] of "a", it only references it internally. Here is the method signature:
public String2(String original) {
this.value = original.value;
this.hash = original.hash;
}
One interned String ("a") equals 2 Objects. And one new String("a") equals one more object. Net effect from code is three objects.
Two objects will be created for this:
String s = new String("abc");
One in the heap and the other in the "string constant pool" (SCP). The reference s will pointing to s always, and GC is not allowed in the SCP area, so all objects on SCP will be destroyed automatically at the time of JVM shutdown.
For example:
Here by using a heap object reference we are getting the corresponding SCP object reference by call of intern()
String s1 = new String("abc");
String s2 = s1.intern(); // SCP object reference
System.out.println(s1==s2); // false
String s3 = "abc";
System.out.println(s2==s3); //True s3 reference to SCP object here
String s = new String("xyz");
The above line will create two object one is in heap and another is in String constant pool.
now if we do this
String s = new String("xyz");
String s1 ="xyz";
the above two statement will create two object.
The first line String s = new String("xyz");will create two object as mentioned
in 1st line and , When String s = "xyz";executes it checks in string constant pool if there is same content object is there or not, since the first line made an entry in string constant pool with "xyz" it returns the same reference and does not create other object.
What if we have these four line together as mentioned bellow.
String s2 = new String("xyz");
String s3 ="xyz";
String s4 = new String("xyz");
String s5 ="xyz";
If we execute the above line we will have three object.
The first and as mentioned will create two object one in heap and
another in String constant poll.
When the second line executes it checks in the string constant poll
and find with "xyz" so it returns the same object, so till second
line we have two objects.
when the third line executes it will create a new object in the heap
since new operator creates object in the heap so till third line will
have 3 objects.
When the fourth line executes it checks in the string constant poll
and find with "xyz" so it returns the same object, so fourth line
we have three objects.
Bonus about the intern() method
When the intern() method is invoked on a String object it looks the
string contained by this String object in the pool, if the string is
found there then the string from the pool is returned. Otherwise, this
String object is added to the pool and a reference to this String
object is returned.
public class TestString {
public static void main(String[] args) {
String s1 = "Test";
String s2 = "Test";
String s3 = new String("Test");
final String s4 = s3.intern();
System.out.println(s1 == s2);
System.out.println(s2 == s3);
System.out.println(s3 == s4);
System.out.println(s1 == s3);
System.out.println(s1 == s4);
System.out.println(s1.equals(s2));
System.out.println(s2.equals(s3));
System.out.println(s3.equals(s4));
System.out.println(s1.equals(s4));
System.out.println(s1.equals(s3));
}
}
//Output
true
false
false
false
true
true
true
true
true
true
See the magic of intern by applying intern method on new string object.
intern is applied here so it will check if "Test" is available in String Constant pool or not since "Test" is available in String constant pool and it will return the same object so s3 has the same reference as s1 and s2 and will get all the result as true
public class TestString {
public static void main(String[] args) {
String s1 = "Test";
String s2 = "Test";
String s3 = new String("Test").intern();
final String s4 = s3.intern();
System.out.println(s1 == s2);
System.out.println(s2 == s3);
System.out.println(s3 == s4);
System.out.println(s1 == s3);
System.out.println(s1 == s4);
System.out.println(s1.equals(s2));
System.out.println(s2.equals(s3));
System.out.println(s3.equals(s4));
System.out.println(s1.equals(s4));
System.out.println(s1.equals(s3));
}
}
true
true
true
true
true
true
true
true
true
true
There are two ways to create string objects in Java:
Using the new operator, i.e.
String s1 = new String("abc");
Using a string literal, i.e.
String s2 = "abc";
Now string allocation is costly in both time and memory so the JVM (Java Virtual Machine) performs some tasks. WHAT TASKS?
See, whenever you are using the new operator the object is created, and the JVM will not look in the string pool. It is just going to create the object, but when you are using the string literals for creating string objects then the JVM will perform the task of looking in the string pool
I.e., when you write
String s2 = "abc";
the JVM will look in the string pool and check if "abc" already exists or not. If it exists then a reference is returned to the already existing string "abc" and a new object is not created and if it doesn't exists then an object is created.
So in your case
(a)
String s1 = new String("abc");
Since new is used the object is created
(b)
String s2 = "abc";
using a string literal an object is created and "abc" is not in the
string pool and therefore the object is created.
(c)
String s2 = "abc";
Again using a string literal and "abc" is in the string pool, and
therefore the object is not created.
You can also check it out by using the following code:
class String_Check
{
public static void main(String[] n)
{
String s1 = new String("abc");
String s2 = "abc";
String s3 = "abc";
if (s1==s2)
System.out.println("s1==s2");
if(s1==s3)
System.out.println("s1==s3");
if(s2==s3)
System.out.println("s2==s3");
}
}
I hope this helps... Note that == is used to see if the objects are equal and the equals(Object) method is used to see if content are equal.
If we execute String s = new String("Brajesh"); , two objects shall be created. One object will be created in string literal pool and another one in heap area.
But if we have already same string literal object, then only one object is created.
like
String s1 ="Brajesh";
String s = new String("Brajesh");//it will create only one object in heap area
Apart from this one additional object is also created in heap area that is char[]'s object. I have attached here snapshot of heap memory.
There are so many random answers and so I am confident that my interviewer will also be not very sure :) :)
I researched a lot and found that hashcode is not the memory address and the variables while debugging don't give the memory address. So, those parameters might confuse.
2 or 3 objects are created, depending on how smart the compiler is.
Nevertheless, your test is junk, because hashCode of Strings is based on the content of the String, and not on their identity. If you want to check for identity, you should use System.identityHashCode or just == comparison.
The compiler and the runtime are allowed (not forced) to optimize string creation whenever possible. So, they optimize literal strings, by using a single literal for the three strings you have.
Anyway, the new operator must return a new object (i.e. a newly allocated one).
String optimization at runtime is possible if the static method String.valueOf is used instead. But I don't know if any caching is actually applied by current JREs (maybe it's more expensive to check a hash table than to just allocate a new String)
String s1="Pune";
String s2="Mumbai";
String s3="Pune";
String s4=new String("Mumbai");
System.out.println("S1 :"+s1.hashCode()); //S1 :2499228
System.out.println("S2 :"+s2.hashCode()); //S2 :-1979126203
System.out.println("S3 :"+s3.hashCode()); //S3 :2499228
System.out.println("S4 :"+s4.hashCode()); //S4 :-1979126203
System.out.println(s2==s4); // false
As we can see in the above program we are getting a similar hashcode for s2 and s4 respectively although we are getting false using == operator. == operator is used for reference comparison.
Two objects have been created at "String s4=new String("Mumbai")", one in heap memory and one in stack memory. Therefore s2 compares with s4 which is created in heap memory, not with stack memory.
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
If we see the code , we can see it will just create a char[] and it will get copied every time with same content get instantiated and yes it will store data in String Constant Pool . 1)Will take from SCP String s1 = "a" String s2 = "a"; 2)Creates a new object String s3 = new String("a"); Curiosity , New Object String s2=new String("a"); In all above code same char[] will get copied.i:e char[] value You can check here
I ran it in the Eclipse debugger. In that context, two objects are created, one with the id 17, the other 22:
java.lang.String overrides the hashCode() method so that the value depends on the content of the string.
As a result, hashCode() does not tell you anything about the number of instances. It may be the same string or may be another instance with no single byte shared. Same about equals(). This explains your output.
Use System.identityHashCode(..) for this kind of research.
And may the source be with you.
#Giulio, You are right.
String s3 = new String("abc"); creates two objects one in heap with reference s3 and another in SCP(Without reference).
and now String s2 = "abc"; doesn't create any new object in SCP because "abc" is already there in SCP.
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = s3.intern();
System.out.println("s1: "+System.identityHashCode(s1));
System.out.println("s2: "+System.identityHashCode(s2));
System.out.println("s3: "+System.identityHashCode(s3));
System.out.println("s4: "+System.identityHashCode(s4));
O/P:s1: 366712642,
s2: 366712642,
s3: 1829164700,
s4: 366712642
As i am not eligible for commenting i wrote it here.
If we run below code in eclipse in debug mode we'll get an idea about how many objects are created with String string = new String("manoj"); Internally it will create String str = "manoj"in String class constructor.
Just check id after hover on reference as shown in below screen shot.
ScreenShot
public static void main(String[] args)
{
String str = "atul";
String string = new String("manoj");
String string2 = "manoj";
System.out.println(str == string);
}
Confused with what exactly happens after the new String("<>") is being called, I found this thread. Your hashcode comparison understanding is not technically correct though.
int hashCode() has been overriden in String class and it returns a value depending on the content of the String literal.
String s1 = new String("Hello");
String s2 = new String("Hello");
So s1.hashCode() = s2.hashCode() = anyStringOfContent_"Hello".hashCode()
**/** Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
**h = 31 * h + val[i];**
}
hash = h;
}
return h;
}**
Now just to explain why is this done, you can actually read the Kathy Sierra book which has a great explanation why developers have done in this manner (basically any objects returning true to equals() method should return same hashCode() value).
If new String() creates 2 objects (one in heap and one in String pool) then what is the use of .intern method ?
intern() method invoked on a String object looks for the string
contained by this String object in the pool, if the string is found
there then the string from the pool is returned. Otherwise, this
String object is added to the pool and a reference to this String
object is returned.
2 objects made out of:
String s = new String("xyz");
1st creating new String object in heap memory (String Pool)
2nd placing "xyz" in string constant pool
There is a concept called string pool in Java. A string pool (string intern pool) is a special storage area in the Java heap. When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object and returning its reference.
So String s = new String(“xyz”) it will create two objects.
The first object will be created in the Java permanent heap memory as part of the argument we are passing - "XYZ". And it will be created in the String Literal Pool.
The second object will be created within the Java heap memory - which will be created as part of the new operator.
Just because all your hash codes are the same does not mean that you are looking at the same object. Two objects are created. Let's break this down.
String s = new String(“xyz”);
In the part ' new String("xyz") ', an address is returned to the new string "xyz". When you say ' String s = ', this assigns that returned address to this object, so that they point to the same place, but the new string and string s are two seperate objects.
I used the hashcode() method to find the number of string objects created.
The hashcode() method digests the data stored in the reference variable into a single hash value.
CASE1:
String s="
Fred";
System.out.println(s.hashCode());
s=s+"47";
System.out.println(s.hashCode());
s=s.substring(2,5);
System.out.println(s.hashCode());
s=s.toUpperCase();
System.out.println(s.hashCode());
s=s.toString();
System.out.println(s.hashCode());
The output is:
Fred--2198155 //1st object ---------------- String s="Fred"
Fred47--2112428622 //2nd object ---------------- s=s+"47"
ed4--100213 //3rd object ---------------- s=s.substring(2,5)
ED4--68469 //4th object ---------------- s=s.toUpperCase()
ED4--68469 //this is retrieved from the string constant pool -------- s=s.toString();
So 4 objects created in total.
CASE 2:
String s="FRED";
System.out.println(s.hashCode());
s=s+"47";
System.out.println(s.hashCode());
s=s.substring(2,5);
System.out.println(s.hashCode());
s=s.toUpperCase();
System.out.println(s.hashCode());
s=s.toString();
System.out.println(s.hashCode());
The output is:
FRED--2166379 //1st object ---------------- String s="Fred"
FRED47--2081891886 //2nd object ---------------- s=s+"47"
ED4--68469 //3rd object ---------------- s=s.substring(2,5)
ED4--68469 //this is retrieved from the string constant pool ------- s=s.toUpperCase()
ED4--68469 //this is retrieved from the string constant pool -------- s=s.toString()
3 objects created in total.
There is a way to find how many objects are created using the new keyword (String s1=new String("Rajesh")).
public class Rajesh {
public static void main(String[] args){
String s1=new String("Rajesh");
System.out.println(s1+s1.intern());
}
}
Output:
RajeshRajesh //s1=Rajesh+s2.intern()=Rajesh
Note: As we know the intern method always hit the string constant pool of heap memory.
String s = new String("xyz");
how many objects has been created in above code?
Only one object has been created in above code, that's in heap memory.
not two object.....
If two objects are created, one is in a heap memory(new operator) and another one is in String constant pool(string literal), if your store below value using String literal ,
String s1 = "xyz";
it will not returns reference of object s in string constant pool. it will create new object in String Constant Pool as s1.
How?
we can check it by using == operator (s == s1) to check the reference type.
If s is already stored in String Constant Pool it give the true, in this case output is false.
So the conclusion is one object is created in above code.
Is doing:
String a = new String();
String b = a;
and doing:
String a = new String();
String b = a.intern();
is the same ?
Actually, the reference are all the same if I test:
String a = new String("te");
String b = a.intern();
String c = a;
String d = "t" + "e";
System.out.print(a.equals(b));
System.out.print(b.equals(c));
System.out.print(a.equals(d));
Cause the String will ever be in the String pool ?
Your equals tests aren't checking for references - they're checking for string equality. You should be using == to check the references for identity. Effectively, you're making the common rookie Java mistake in reverse - usually people use == when they should be using equals. In this particular case, all of those will print false, because there are two String objects involved (the string from the constant pool, and the new string created in the first line). If we call these #1 and #2 respectively, we end up with:
a = #2 // Explicit call to string constructor
b = #1 // intern will return reference to constant pool instance
c = #2 // Direct assignment
d = #1 // Equivalent string constant, so reference to constant pool instance
However, you may find this interesting:
String a = "te";
String b = a.intern();
String c = "t" + "e";
System.out.println(a == b); // true
System.out.println(a == c); // true
"te" and "t" + "e" are equal constant string expressions, so end up as references to a single string, and calling intern on a string already in the literal pool won't have any effect.
To start off: "t" + "e" is a String literal, because it will be optimised by the compiler. This string literal is also used in this line:
String a = new String("te");
Now, the String(String) constructor makes a physical copy of the String. So, this means that a and d are not the same object.
Then: String.equals(String) compares two Strings. It says if the content was equal and not the object. This means you might have two different String objects which have the same sequence of characters, which will make the String.equals(String) return true.
String.intern() puts the String in the String pool, if it isn't yet in it. But this method can't change the object itself. So this code example will print false:
String literal = "lit";
String nonLiteral = "abclit".substring(3); // equals "lit"
nonLiteral.intern(); // "lit" was already in the String pool
// but `nonLiteral` is still `nonLiteral`
System.out.println(literal == nonLiteral); // false
However if you would do this: it will return true:
String literal = "lit";
String nonLiteral = "abclit".substring(3); // equals "lit"
nonLiteral = nonLiteral.intern(); // "lit" was already in the String pool and
// it will return the object `literal`.
// Now the value is replaced.
System.out.println(literal == nonLiteral); // true
If that string value has already been interned from a different String instance, intern() will return the earlier instance.
Using equals doesn't test the equality of the references. It tests the equality of the contents of the String. You need to use == to test the equality of the references.
To answer your question, no, it's not the same. The first snippet assigns two references (a and b) to the same String. The second one creates a String, assigns it to a, then interns the String and assigns the String that the intern pool returns to b. a and b could thus refer to two different String instances (and certainly will, because the empty String is in the pool for sure, thus intern() will not return the STring referred to by a, but will returned the pooled empty String)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java Strings: “String s = new String(”silly“);”
If i write
String s= new String("how many object b created by this method ");
how many reference objects and objects will be created in comparison to doing it this way:
Sting s1="Is this method is good as compare to upper";
Using String s= new String("how many object b created by this method "); creates a new object 's' of String class, and you are passing the string "how many object b created by this method" to its constructor.
In String s1="Is this method is good as compare to upper"; 's1' is a string literal. On string literals:
Each time your code
create a string literal, the JVM
checks the string literal pool first.
If the string already exists in the
pool, a reference to the pooled
instance returns. If the string does
not exist in the pool, a new String
object instantiates, then is placed in
the pool. Java can make this
optimization since strings are
immutable and can be shared without
fear of data corruption.
source
The above concept is related to string interning; all literal strings and string-valued constant expressions are interned in Java [source]. So basically, using String s1="Is this method is good as compare to upper"; will create a new object only if "Is this method is good as compare to upper" is not already in the pool.
Using String s1="some string" doesn't create new String object. There is existing String object for every String literal already.
String literals with same values are represented with single String object, so if you use String s1="some string"; String s2="some string"; both s1, s2 refer to same "some string" object.
new String("...") creates one new String object, which uses same data as String object for value "..." passed to constructor.
Consider:
String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2);
Will print false.
However
String s1 = "hi";
String s2 = "h1";
System.out.println(s1 == s2);
Will print true.
And
String s1 = "hi";
String s2 = new String("hi");
System.out.println(s1 == s2);
Will print false.
This is why you should always use String.equals when comparing Strings instead of ==.
But don't take my word for it... Check this excerpt from the Java Language Specification JLS 3.10:
Thus, the test program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }
produces the output:
true true true true false true
This example illustrates six points:
Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
There are two ways to create a String object in Java:
Using the new operator. For example,
String str = new String("Hello");
Using a string literal or constant expression). For example,
String str="Hello"; (string literal) or
String str="Hel" + "lo"; (string constant expression).
String Literal Pool :
String allocation, like all object
allocation, proves costly in both time
and memory. The JVM performs some
trickery while instantiating string
literals to increase performance and
decrease memory overhead. To cut down
the number of String objects created
in the JVM, the String class keeps a
pool of strings. Each time your code
create a string literal, the JVM
checks the string literal pool first.
If the string already exists in the
pool, a reference to the pooled
instance returns. If the string does
not exist in the pool, a new String
object instantiates, then is placed in
the pool.
Creating a String object using NEW keyword always creates an object in the heap containing the desired string and the reference of the created object in the heap is returned.
Creating a String object without NEW keyword (using literal) first checks for an existing string with the same data in the String literal pool, if found, the same reference from the String literal pool is returned, else, a new one is created in the String literal pool and its reference is returned.
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 9 years ago.
I am confused about StringPool in Java. I came across this while reading the String chapter in Java. Please help me understand, in layman terms, what StringPool actually does.
This prints true (even though we don't use equals method: correct way to compare strings)
String s = "a" + "bc";
String t = "ab" + "c";
System.out.println(s == t);
When compiler optimizes your string literals, it sees that both s and t have same value and thus you need only one string object. It's safe because String is immutable in Java.
As result, both s and t point to the same object and some little memory saved.
Name 'string pool' comes from the idea that all already defined string are stored in some 'pool' and before creating new String object compiler checks if such string is already defined.
I don't think it actually does much, it looks like it's just a cache for string literals. If you have multiple Strings who's values are the same, they'll all point to the same string literal in the string pool.
String s1 = "Arul"; //case 1
String s2 = "Arul"; //case 2
In case 1, literal s1 is created newly and kept in the pool. But in case 2, literal s2 refer the s1, it will not create new one instead.
if(s1 == s2) System.out.println("equal"); //Prints equal.
String n1 = new String("Arul");
String n2 = new String("Arul");
if(n1 == n2) System.out.println("equal"); //No output.
http://p2p.wrox.com/java-espanol/29312-string-pooling.html
Let's start with a quote from the virtual machine spec:
Loading of a class or interface that contains a String literal may create a new String object (§2.4.8) to represent that literal. This may not occur if the a String object has already been created to represent a previous occurrence of that literal, or if the String.intern method has been invoked on a String object representing the same string as the literal.
This may not occur - This is a hint, that there's something special about String objects. Usually, invoking a constructor will always create a new instance of the class. This is not the case with Strings, especially when String objects are 'created' with literals. Those Strings are stored in a global store (pool) - or at least the references are kept in a pool, and whenever a new instance of an already known Strings is needed, the vm returns a reference to the object from the pool. In pseudo code, it may go like that:
1: a := "one"
--> if(pool[hash("one")] == null) // true
pool[hash("one") --> "one"]
return pool[hash("one")]
2: b := "one"
--> if(pool[hash("one")] == null) // false, "one" already in pool
pool[hash("one") --> "one"]
return pool[hash("one")]
So in this case, variables a and b hold references to the same object. IN this case, we have (a == b) && (a.equals(b)) == true.
This is not the case if we use the constructor:
1: a := "one"
2: b := new String("one")
Again, "one" is created on the pool but then we create a new instance from the same literal, and in this case, it leads to (a == b) && (a.equals(b)) == false
So why do we have a String pool? Strings and especially String literals are widely used in typical Java code. And they are immutable. And being immutable allowed to cache String to save memory and increase performance (less effort for creation, less garbage to be collected).
As programmers we don't have to care much about the String pool, as long as we keep in mind:
(a == b) && (a.equals(b)) may be true or false (always use equals to compare Strings)
Don't use reflection to change the backing char[] of a String (as you don't know who is actualling using that String)
When the JVM loads classes, or otherwise sees a literal string, or some code interns a string, it adds the string to a mostly-hidden lookup table that has one copy of each such string. If another copy is added, the runtime arranges it so that all the literals refer to the same string object. This is called "interning". If you say something like
String s = "test";
return (s == "test");
it'll return true, because the first and second "test" are actually the same object. Comparing interned strings this way can be much, much faster than String.equals, as there's a single reference comparison rather than a bunch of char comparisons.
You can add a string to the pool by calling String.intern(), which will give you back the pooled version of the string (which could be the same string you're interning, but you'd be crazy to rely on that -- you often can't be sure exactly what code has been loaded and run up til now and interned the same string). The pooled version (the string returned from intern) will be equal to any identical literal. For example:
String s1 = "test";
String s2 = new String("test"); // "new String" guarantees a different object
System.out.println(s1 == s2); // should print "false"
s2 = s2.intern();
System.out.println(s1 == s2); // should print "true"
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
This code separates a string into tokens and stores them in an array of strings, and then compares a variable with the first home ... why isn't it working?
public static void main(String...aArguments) throws IOException {
String usuario = "Jorman";
String password = "14988611";
String strDatos = "Jorman 14988611";
StringTokenizer tokens = new StringTokenizer(strDatos, " ");
int nDatos = tokens.countTokens();
String[] datos = new String[nDatos];
int i = 0;
while (tokens.hasMoreTokens()) {
String str = tokens.nextToken();
datos[i] = str;
i++;
}
//System.out.println (usuario);
if ((datos[0] == usuario)) {
System.out.println("WORKING");
}
}
Use the string.equals(Object other) function to compare strings, not the == operator.
The function checks the actual contents of the string, the == operator checks whether the references to the objects are equal. Note that string constants are usually "interned" such that two constants with the same value can actually be compared with ==, but it's better not to rely on that.
if (usuario.equals(datos[0])) {
...
}
NB: the compare is done on 'usuario' because that's guaranteed non-null in your code, although you should still check that you've actually got some tokens in the datos array otherwise you'll get an array-out-of-bounds exception.
Meet Jorman
Jorman is a successful businessman and has 2 houses.
But others don't know that.
Is it the same Jorman?
When you ask neighbours from either Madison or Burke streets, this is the only thing they can say:
Using the residence alone, it's tough to confirm that it's the same Jorman. Since they're 2 different addresses, it's just natural to assume that those are 2 different persons.
That's how the operator == behaves. So it will say that datos[0]==usuario is false, because it only compares the addresses.
An Investigator to the Rescue
What if we sent an investigator? We know that it's the same Jorman, but we need to prove it. Our detective will look closely at all physical aspects. With thorough inquiry, the agent will be able to conclude whether it's the same person or not. Let's see it happen in Java terms.
Here's the source code of String's equals() method:
It compares the Strings character by character, in order to come to a conclusion that they are indeed equal.
That's how the String equals method behaves. So datos[0].equals(usuario) will return true, because it performs a logical comparison.
It's good to notice that in some cases use of "==" operator can lead to the expected result, because the way how java handles strings - string literals are interned (see String.intern()) during compilation - so when you write for example "hello world" in two classes and compare those strings with "==" you could get result: true, which is expected according to specification; when you compare same strings (if they have same value) when the first one is string literal (ie. defined through "i am string literal") and second is constructed during runtime ie. with "new" keyword like new String("i am string literal"), the == (equality) operator returns false, because both of them are different instances of the String class.
Only right way is using .equals() -> datos[0].equals(usuario). == says only if two objects are the same instance of object (ie. have same memory address)
Update: 01.04.2013 I updated this post due comments below which are somehow right. Originally I declared that interning (String.intern) is side effect of JVM optimization. Although it certainly save memory resources (which was what i meant by "optimization") it is mainly feature of language
The == operator checks if the two references point to the same object or not.
.equals() checks for the actual string content (value).
Note that the .equals() method belongs to class Object (super class of all classes). You need to override it as per you class requirement, but for String it is already implemented and it checks whether two strings have the same value or not.
Case1)
String s1 = "Stack Overflow";
String s2 = "Stack Overflow";
s1 == s1; // true
s1.equals(s2); // true
Reason: String literals created without null are stored in the string pool in the permgen area of the heap. So both s1 and s2 point to the same object in the pool.
Case2)
String s1 = new String("Stack Overflow");
String s2 = new String("Stack Overflow");
s1 == s2; // false
s1.equals(s2); // true
Reason: If you create a String object using the `new` keyword a separate space is allocated to it on the heap.
equals() function is a method of Object class which should be overridden by programmer. String class overrides it to check if two strings are equal i.e. in content and not reference.
== operator checks if the references of both the objects are the same.
Consider the programs
String abc = "Awesome" ;
String xyz = abc;
if(abc == xyz)
System.out.println("Refers to same string");
Here the abc and xyz, both refer to same String "Awesome". Hence the expression (abc == xyz) is true.
String abc = "Hello World";
String xyz = "Hello World";
if(abc == xyz)
System.out.println("Refers to same string");
else
System.out.println("Refers to different strings");
if(abc.equals(xyz))
System.out.prinln("Contents of both strings are same");
else
System.out.prinln("Contents of strings are different");
Here abc and xyz are two different strings with the same content "Hello World". Hence here the expression (abc == xyz) is false where as (abc.equals(xyz)) is true.
Hope you understood the difference between == and <Object>.equals()
Thanks.
== tests for reference equality.
.equals() tests for value equality.
Consequently, if you actually want to test whether two strings have the same value you should use .equals() (except in a few situations where you can guarantee that two strings with the same value will be represented by the same object eg: String interning).
== is for testing whether two strings are the same Object.
// These two have the same value
new String("test").equals("test") ==> true
// ... but they are not the same object
new String("test") == "test" ==> false
// ... neither are these
new String("test") == new String("test") ==> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" ==> true
// concatenation of string literals happens at compile time resulting in same objects
"test" == "te" + "st" ==> true
// but .substring() is invoked at runtime, generating distinct objects
"test" == "!test".substring(1) ==> false
It is important to note that == is much cheaper than equals() (a single pointer comparision instead of a loop), thus, in situations where it is applicable (i.e. you can guarantee that you are only dealing with interned strings) it can present an important performance improvement. However, these situations are rare.
Instead of
datos[0] == usuario
use
datos[0].equals(usuario)
== compares the reference of the variable where .equals() compares the values which is what you want.
Let's analyze the following Java, to understand the identity and equality of Strings:
public static void testEquality(){
String str1 = "Hello world.";
String str2 = "Hello world.";
if (str1 == str2)
System.out.print("str1 == str2\n");
else
System.out.print("str1 != str2\n");
if(str1.equals(str2))
System.out.print("str1 equals to str2\n");
else
System.out.print("str1 doesn't equal to str2\n");
String str3 = new String("Hello world.");
String str4 = new String("Hello world.");
if (str3 == str4)
System.out.print("str3 == str4\n");
else
System.out.print("str3 != str4\n");
if(str3.equals(str4))
System.out.print("str3 equals to str4\n");
else
System.out.print("str3 doesn't equal to str4\n");
}
When the first line of code String str1 = "Hello world." executes, a string \Hello world."
is created, and the variable str1 refers to it. Another string "Hello world." will not be created again when the next line of code executes because of optimization. The variable str2 also refers to the existing ""Hello world.".
The operator == checks identity of two objects (whether two variables refer to same object). Since str1 and str2 refer to same string in memory, they are identical to each other. The method equals checks equality of two objects (whether two objects have same content). Of course, the content of str1 and str2 are same.
When code String str3 = new String("Hello world.") executes, a new instance of string with content "Hello world." is created, and it is referred to by the variable str3. And then another instance of string with content "Hello world." is created again, and referred to by
str4. Since str3 and str4 refer to two different instances, they are not identical, but their
content are same.
Therefore, the output contains four lines:
Str1 == str2
Str1 equals str2
Str3! = str4
Str3 equals str4
You should use string equals to compare two strings for equality, not operator == which just compares the references.
It will also work if you call intern() on the string before inserting it into the array.
Interned strings are reference-equal (==) if and only if they are value-equal (equals().)
public static void main (String... aArguments) throws IOException {
String usuario = "Jorman";
String password = "14988611";
String strDatos="Jorman 14988611";
StringTokenizer tokens=new StringTokenizer(strDatos, " ");
int nDatos=tokens.countTokens();
String[] datos=new String[nDatos];
int i=0;
while(tokens.hasMoreTokens()) {
String str=tokens.nextToken();
datos[i]= str.intern();
i++;
}
//System.out.println (usuario);
if(datos[0]==usuario) {
System.out.println ("WORKING");
}
Generally .equals is used for Object comparison, where you want to verify if two Objects have an identical value.
== for reference comparison (are the two Objects the same Object on the heap) & to check if the Object is null. It is also used to compare the values of primitive types.
== operator compares the reference of an object in Java. You can use string's equals method .
String s = "Test";
if(s.equals("Test"))
{
System.out.println("Equal");
}
If you are going to compare any assigned value of the string i.e. primitive string, both "==" and .equals will work, but for the new string object you should use only .equals, and here "==" will not work.
Example:
String a = "name";
String b = "name";
if(a == b) and (a.equals(b)) will return true.
But
String a = new String("a");
In this case if(a == b) will return false
So it's better to use the .equals operator...
The == operator is a simple comparison of values.
For object references the (values) are the (references). So x == y returns true if x and y reference the same object.
I know this is an old question but here's how I look at it (I find very useful):
Technical explanations
In Java, all variables are either primitive types or references.
(If you need to know what a reference is: "Object variables" are just pointers to objects. So with Object something = ..., something is really an address in memory (a number).)
== compares the exact values. So it compares if the primitive values are the same, or if the references (addresses) are the same. That's why == often doesn't work on Strings; Strings are objects, and doing == on two string variables just compares if the address is same in memory, as others have pointed out. .equals() calls the comparison method of objects, which will compare the actual objects pointed by the references. In the case of Strings, it compares each character to see if they're equal.
The interesting part:
So why does == sometimes return true for Strings? Note that Strings are immutable. In your code, if you do
String foo = "hi";
String bar = "hi";
Since strings are immutable (when you call .trim() or something, it produces a new string, not modifying the original object pointed to in memory), you don't really need two different String("hi") objects. If the compiler is smart, the bytecode will read to only generate one String("hi") object. So if you do
if (foo == bar) ...
right after, they're pointing to the same object, and will return true. But you rarely intend this. Instead, you're asking for user input, which is creating new strings at different parts of memory, etc. etc.
Note: If you do something like baz = new String(bar) the compiler may still figure out they're the same thing. But the main point is when the compiler sees literal strings, it can easily optimize same strings.
I don't know how it works in runtime, but I assume the JVM doesn't keep a list of "live strings" and check if a same string exists. (eg if you read a line of input twice, and the user enters the same input twice, it won't check if the second input string is the same as the first, and point them to the same memory). It'd save a bit of heap memory, but it's so negligible the overhead isn't worth it. Again, the point is it's easy for the compiler to optimize literal strings.
There you have it... a gritty explanation for == vs. .equals() and why it seems random.
#Melkhiah66 You can use equals method instead of '==' method to check the equality.
If you use intern() then it checks whether the object is in pool if present then returns
equal else unequal. equals method internally uses hashcode and gets you the required result.
public class Demo
{
public static void main(String[] args)
{
String str1 = "Jorman 14988611";
String str2 = new StringBuffer("Jorman").append(" 14988611").toString();
String str3 = str2.intern();
System.out.println("str1 == str2 " + (str1 == str2)); //gives false
System.out.println("str1 == str3 " + (str1 == str3)); //gives true
System.out.println("str1 equals str2 " + (str1.equals(str2))); //gives true
System.out.println("str1 equals str3 " + (str1.equals(str3))); //gives true
}
}
The .equals() will check if the two strings have the same value and return the boolean value where as the == operator checks to see if the two strings are the same object.
Someone said on a post higher up that == is used for int and for checking nulls.
It may also be used to check for Boolean operations and char types.
Be very careful though and double check that you are using a char and not a String.
for example
String strType = "a";
char charType = 'a';
for strings you would then check
This would be correct
if(strType.equals("a")
do something
but
if(charType.equals('a')
do something else
would be incorrect, you would need to do the following
if(charType == 'a')
do something else
a==b
Compares references, not values. The use of == with object references is generally limited to the following:
Comparing to see if a reference is null.
Comparing two enum values. This works because there is only one object for each enum constant.
You want to know if two references are to the same object
"a".equals("b")
Compares values for equality. Because this method is defined in the Object class, from which all other classes are derived, it's automatically defined for every class. However, it doesn't perform an intelligent comparison for most classes unless the class overrides it. It has been defined in a meaningful way for most Java core classes. If it's not defined for a (user) class, it behaves the same as ==.
Use Split rather than tokenizer,it will surely provide u exact output
for E.g:
string name="Harry";
string salary="25000";
string namsal="Harry 25000";
string[] s=namsal.split(" ");
for(int i=0;i<s.length;i++)
{
System.out.println(s[i]);
}
if(s[0].equals("Harry"))
{
System.out.println("Task Complete");
}
After this I am sure you will get better results.....