• (2 Pages)
  • +
  • 1
  • 2

The String Pool Rate Topic: ***** 2 Votes

#1 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,023
  • Joined: 15-July 08

Posted 24 August 2010 - 06:35 PM

*
POPULAR

The String Pool
Sun made an optimization that is rather confusing to many new Java programmers called the String Pool. It allows for Strings, which are one of the most used Objects to optimize themselves and save space. An important point to make is that the String Pool only applies to String literals, meaning their value was assigned, not constructed using a String constructor. Let me start off with an example:

public class Main {
	
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = "abc";
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));		
	}
	
}



If you run this program, you get this:

Quote

s1 = abc
s2 = abc
s1 == s2? true
s1.equals(s2)? true


Most beginners are told to only compare strings using the .equals() method, simply because it is safer for beginners, however, what is confusing about my program above is that the == operator actually said those two were the same memory location too. How is s1 == s2? I clearly defined 2 different variables! An important concept about Java that you may not know is that symbols (variable names) aren't actually the object that they are defined as. They actually hold a reference to the spot in memory where the actual object is kept. Since Strings are SO commonly used, Strings literals that are the same are given the same address so that it saves memory and doesn't have to make another. Think about it as if there can only be one of each String in there and anything matching is assigned a reference to that String. However, once all references are gone, then the object is erased. However, once they change, the addresses are different:

public class Main {
	
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = "abc";
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
		s2 += "abc";
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}



This outputs this:

Quote

s1 = abc
s2 = abc
s1 == s2? true
s1.equals(s2)? true
s1 = abc
s2 = abcabc
s1 == s2? false
s1.equals(s2)? false


HOWEVER, if for any reason you want the variables to not occupy the same location in memory, there are two ways to do this. First, you can use the String constructor, since those are not put into the pool:

public class Main {
	
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = new String("abc");
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}



This code says that == is false. And just to prove a point, let's make both of them use constructors:

public class Main {
	
	public static void main(String[] args) {
		String s1 = new String("abc");
		String s2 = new String("abc");
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}



That code yields:

Quote

s1 = abc
s2 = abc
s1 == s2? false
s1.equals(s2)? true


OR you can assign them in different steps, forcing it to occupy a diffent address for each addition. (First they are the same, then s1 is moved to another spot to add on the "c" and the same for s2):

public class Main {
	
	public static void main(String[] args) {
		String s1 = "ab";
		String s2 = "a";
		s1 += "c";
		s2 += "bc";
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}



Quote

s1 = abc
s2 = abc
s1 == s2? false
s1.equals(s2)? true


However, there is a way for a literal and a constructor value (assuming value is the same) to == each other. cfoley introduced me to the intern() method of the String class. What this method does is it looks at its value, and if it matches a value ALREADY IN the String pool, it returns a reference to the object in the pool, else it adds itself to the pool. Observe:

public class Main {
	
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = new String("abc");
		s2 = s2.intern();
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}



This returns:

Quote

s1 = abc
s2 = abc
s1 == s2? true
s1.equals(s2)? true


Cool huh? This happens because s1 is ASSIGNED to "abc" and is added to the pool. s2, however, is constructed to "abc", but not added to the pool. But the intern() method sees that the VALUE "abc" is already in the pool and thus returns the reference to s1. I got a challenge problem for you now. Will s1 == s2 in the following code?

public class Main {
	
	public static void main(String[] args) {
		String s1 = new String("abc");
		String s2 = new String("abc");
		s2 = s2.intern();
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}





... The answer is no. The intern() method is called, but neither s1 nor s2 is in the pool so all the intern() method does is add it to the pool. To make THESE ==, you must call intern() twice so that there is already a reference in the pool (from the first call).

public class Main {
	
	public static void main(String[] args) {
		String s1 = new String("abc");
		String s2 = new String("abc");
		s2 = s2.intern();
		s1 = s1.intern();
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}


Quote

s1 = abc
s2 = abc
s1 == s2? true
s1.equals(s2)? true


That's all I have on that for now! Make sure to give cfoley kudos for helping me study the intern() method! I encourage you all to experiment with this, as I'm sure there is SOMETHING that I missed in this huge concept.

Is This A Good Question/Topic? 12
  • +

Replies To: The String Pool

#2 NeoTifa  Icon User is offline

  • Whorediot
  • member icon





Reputation: 2586
  • View blog
  • Posts: 15,618
  • Joined: 24-September 08

Posted 24 August 2010 - 06:42 PM

So you went through with it, huh? ;D
Was This Post Helpful? 0
  • +
  • -

#3 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,023
  • Joined: 15-July 08

Posted 24 August 2010 - 06:47 PM

Yeap...Gonna make 1 or two additions I left out.
Was This Post Helpful? 0
  • +
  • -

#4 Luckless  Icon User is offline

  • </luck>
  • member icon

Reputation: 292
  • View blog
  • Posts: 1,146
  • Joined: 31-August 09

Posted 24 August 2010 - 07:27 PM

was considering doing this with all the posts about == around. Glad you beat me to it, because I would have done it an injustice. My brain is fried because Calc II is kicking my butt.
Was This Post Helpful? 0
  • +
  • -

#5 sunilantil  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 22-August 10

Posted 24 August 2010 - 11:58 PM

Quote

public class Main {
	
	public static void main(String[] args) {
		String s1 = new String("abc");
		String s2 = new String("abc");
		s2 = s2.intern();
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s1 == s2? " + (s1 == s2));
		System.out.println("s1.equals(s2)? " + (s1.equals

(s2)));
		
	}
	
}





... The answer is no. The intern() method is called, but neither s1 nor s2 is in the pool so all the intern() method does is add it to the pool. To make THESE ==, you must call intern() twice so that there is already a reference in the pool (from the first call).


1.but neither s1 nor s2 is in the pool {This statement is right}
2.so all the intern() method does is add it to the pool {some confusion}

Hello Sir

in above code i mention to points 1. 2. First point is clear to understand
But in second point i have some confusion which i explain as

let us consider
String str = new String("abc");

tell me how many objects will Be created?
my answer is two objects will be created one is String pool for literal constant "abc" and another on the heap and reff. is assigned to str variable.

Is it right?

if i am right then first intern() methods binds the first object to the pool object tell me yes Or No please?

second times it binds the second object tell me i am right or not?


is there any explanation please tell as possible
Thanks
Sunil Kumar

This post has been edited by Locke: 25 August 2010 - 10:50 AM
Reason for edit:: There were some missing tags.

Was This Post Helpful? 0
  • +
  • -

#6 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1940
  • View blog
  • Posts: 4,029
  • Joined: 11-December 07

Posted 25 August 2010 - 02:30 AM

Nice tutorial. I wasn't expecting credit but thanks anyway. :)
Was This Post Helpful? 1
  • +
  • -

#7 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,023
  • Joined: 15-July 08

Posted 25 August 2010 - 03:45 AM

View Postsunilantil, on 25 August 2010 - 01:58 AM, said:

...
let us consider
String str = new String("abc");

tell me how many objects will Be created?
my answer is two objects will be created one is String pool for literal constant "abc" and another on the heap and reff. is assigned to str variable.

Is it right?


No. A single object is made with the constructor. Only String literals or the intern() method put it into the pool.

View Postsunilantil, on 25 August 2010 - 01:58 AM, said:

if i am right then first intern() methods binds the first object to the pool object tell me yes Or No please?

second times it binds the second object tell me i am right or not?


is there any explanation please tell as possible
Thanks
Sunil Kumar


First time intern() is called, it either returns a String from the pool (if there already, which in my last sample, is not) or adds it to the pool (the way that happens). The second time called, it returns the pooled String.
Was This Post Helpful? 0
  • +
  • -

#8 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1940
  • View blog
  • Posts: 4,029
  • Joined: 11-December 07

Posted 25 August 2010 - 04:09 AM

View PostDogstopper, on 25 August 2010 - 10:45 AM, said:

View Postsunilantil, on 25 August 2010 - 01:58 AM, said:

...
let us consider
String str = new String("abc");

tell me how many objects will Be created?
my answer is two objects will be created one is String pool for literal constant "abc" and another on the heap and reff. is assigned to str variable.

Is it right?


No. A single object is made with the constructor. Only String literals or the intern() method put it into the pool.


Are you sure? In that example there is a literal and a constructor.
Was This Post Helpful? 0
  • +
  • -

#9 SpeedisaVirus  Icon User is offline

  • Baller
  • member icon

Reputation: 114
  • View blog
  • Posts: 855
  • Joined: 06-October 08

Posted 25 August 2010 - 06:58 AM

Good stuff. I suspected there was string pooling going on but never bothered to look into it. Did not know about intern() which is cool.
Was This Post Helpful? 0
  • +
  • -

#10 eCoder  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 22
  • Joined: 22-August 10

Posted 25 August 2010 - 10:20 PM

nicey! nicey! <3 intern()...you too dogstoppper <3...lolzzz
Was This Post Helpful? 0
  • +
  • -

#11 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,023
  • Joined: 15-July 08

Posted 27 August 2010 - 12:58 PM

View Postcfoley, on 25 August 2010 - 06:09 AM, said:

Are you sure? In that example there is a literal and a constructor.


I'm pretty sure that constructors don't get put on the pool...If you find out otherwise, feel free to PM me with the fix!
Was This Post Helpful? 0
  • +
  • -

#12 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,470
  • Joined: 27-December 08

Posted 27 August 2010 - 06:10 PM

I can confirm that. If you use a constructor, the String won't be added to the String pool.
Was This Post Helpful? 0
  • +
  • -

#13 king_009  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 37
  • Joined: 20-August 09

Posted 04 September 2010 - 01:25 AM

Nice post dude....
learnt a new concept of intern(). :bananaman:
wow!!!
thanks for sharing.... :clap:
Was This Post Helpful? 0
  • +
  • -

#14 stalks  Icon User is offline

  • New D.I.C Head

Reputation: 8
  • View blog
  • Posts: 20
  • Joined: 07-October 10

Posted 07 October 2010 - 01:37 PM

View PostDogstopper, on 27 August 2010 - 11:58 AM, said:

I'm pretty sure that constructors don't get put on the pool...If you find out otherwise, feel free to PM me with the fix!


The newly constructed String object doesn't get put in the pool, but I believe the literal String that was passed as an argument to the constructor does (which I think is what cfoley was referring to).
The String object returned from intern will be the same object as the literal that was passed in to the constructor.

It doesn't affect your code, just the explanation of what's happening.
Was This Post Helpful? 2
  • +
  • -

#15 Guest_chandu*


Reputation:

Posted 20 November 2010 - 08:57 AM

Excellent tutorial!
Was This Post Helpful? 0

  • (2 Pages)
  • +
  • 1
  • 2