Author Topic:   String literals
rahul_mkar
ranch hand
posted May 11, 2000 11:37 PM             
can anyone tell me why this is true
("String".toString() == "String")

and
why this is false

(" String ".trim() == "String")

thanx

Deepa
unregistered
posted May 12, 2000 06:50 AM           
("String".toString() == "String")

This is true because "String" is in the literal pool and both point to the same reference in the memory.

and
why this is false

(" String ".trim() == "String")
This is false because trim() returns a new string object after removing spaces and hence it will have a different reference in memory. So == fails.
Hope this helps.

maha anna
bartender
posted May 12, 2000 08:13 AM             
Deepa,rahul_mkar

I have written a small program fou you to undestand this String class and its methods return. Go through this and verify your answer with the program output I have given below. I had selected some random cases. You can also add some more cases and analyze. This test will definitly improve your understanding of the methods of String class and how it defers from the other primitive wrapper classes.
regds
maha anna.


class Test {
public static void main(String[] args) {
String deepaLowercaseStr = new String("deepa");
String deepaUppercaseStr = new String("DEEPA");

//case 1
if(deepaLowercaseStr.toString() == deepaLowercaseStr)
System.out.println("Pass1");
else
System.out.println("Pass1 failed");

//case 2
if(deepaUppercaseStr.toString() == deepaUppercaseStr)
System.out.println("Pass2");
else
System.out.println("Pass2 failed");

//case 3
if(deepaUppercaseStr.toString() == deepaLowercaseStr)
System.out.println("Pass3");
else
System.out.println("Pass3 failed");
//case 4
if(deepaUppercaseStr.toLowerCase() == deepaLowercaseStr)
System.out.println("Pass4");
else
System.out.println("Pass4 failed");
//case 5

if(deepaLowercaseStr.toUpperCase() == deepaUppercaseStr)
System.out.println("Pass5");
else
System.out.println("Pass5 failed");
//case 6

if(deepaLowercaseStr.trim() == deepaLowercaseStr)
System.out.println("Pass6");
else
System.out.println("Pass6 failed");
//case 7

if(deepaLowercaseStr.replace(' ',' ') == deepaLowercaseStr)
System.out.println("Pass7");
else
System.out.println("Pass7 failed");
//case 8

if(deepaUppercaseStr.concat("") == deepaUppercaseStr)
System.out.println("Pass8");
else
System.out.println("Pass8 failed");
//case 9

if(deepaUppercaseStr.concat(" ") == deepaUppercaseStr)
System.out.println("Pass9");
else
System.out.println("Pass9 failed");
//case 10

if(deepaLowercaseStr.trim() == " deepa ".trim())
System.out.println("Pass10");
else
System.out.println("Pass10 failed");
//case 11

if(deepaLowercaseStr.substring(0) == " deepa ".trim())
System.out.println("Pass11");
else
System.out.println("Pass11 failed");
//case 12

if(deepaLowercaseStr.substring(0,deepaLowercaseStr.length()) == " deepa ".trim())
System.out.println("Pass12");
else
System.out.println("Pass12 failed");
//case 13

if(deepaLowercaseStr.trim() == "deepa".trim())
System.out.println("Pass13");
else
System.out.println("Pass13 failed");
//case 14

if(deepaLowercaseStr.trim() == deepaLowercaseStr)
System.out.println("Pass14");
else
System.out.println("Pass14 failed");

}
}

Output
------



Pass1
Pass2
Pass3 failed
Pass4 failed
Pass5 failed
Pass6
Pass7
Pass8
Pass9 failed
Pass10 failed
Pass11 failed
Pass12 failed
Pass13 failed
Pass14

[This message has been edited by maha anna (edited May 12, 2000).]

bongadi
greenhorn
posted May 12, 2000 09:41 AM             
Hi!,
I will come back to Rahul's question


("String".toString() == "String")

it is true because ...


20.12.8 public String toString()

A reference to this object (which is, after all, already a String) is returned.

BUT


(" String ".trim() == "String")

it is false because ...

20.12.37 public String trim()

If this String object represents an empty character sequence, or the first and last characters of character
sequence represented by this String object both have codes greater than \u0020 (the space character),
then a reference to this String object is returned.

Otherwise, if there is no character with a code greater than \u0020 in the string, then a new String
object representing an empty string is created and returned.

Otherwise, let k be the index of the first character in the string whose code is greater than \u0020, and let
m be the index of the last character in the string whose code is greater than \u0020. A new String object
is created, representing the substring of this string that begins with the character at index k and ends with
the character at index m-that is, the result of this.substring(k, m+1).

This method may be used to trim whitespace (§20.5.19) from the beginning and end of a string; in fact, it
trims all ASCII control characters as well.

HOWEVER

  

if("you".trim() == "you")
System.out.println(" true ");
else
System.out.println(" false ");

PRINTS ``true''

Why is that

[This message has been edited by bongadi (edited May 12, 2000).]

bongadi
greenhorn
posted May 12, 2000 09:43 AM             
My test program is similar to Maha's co check it out

public class AQuestion
{

public static void printline() {
System.out.print("-----------------------------------------------------");
System.out.println("-------------------");
}

public static void main(String args[])
{

System.out.print("\"STRING\""+".toUpperCase()"+"==" +" \"STRING\""+":>");
if("STRING".toUpperCase() == "STRING")
System.out.println("\t\t\t Equal");
else
System.out.println("\t\t\t Not Equal");

printline();

System.out.print("\"string\""+".toLowerCase()" +"==" +"\"string\""+":>");
if("\"string\"".toUpperCase() == "\"string\"")
System.out.println("\t\t\t Equal");
else
System.out.println("\t\t\t Not Equal");

printline();

System.out.print("\"STRING\""+".concat(\"\")"+" == "+"\"STRING\""+":>");
if ( "\"STRING\"".concat("") == "\"STRING\"")
System.out.println("\t\t\t Equal");
else
System.out.println("\t\t\t Not Equal");

printline();
System.out.print("\"STRING\"" + ".replace(\'I\'"+ "," + "\'I\')" + " == "
+ "\"STRING\"" + ":>");

if ( "STRING".replace('I','I') == "STRING")
System.out.println("\t\t\t Equal");
else
System.out.println("\t\t\t Not Equal");

printline();
System.out.print("\"STRING\"" + ".substring(0)"+" == "+"\"STRING\""+":>");

if ( "STRING".substring(0) == "STRING") {
System.out.println("\t\t\t Equal");
} else {
System.out.println("\t\t\t Not Equal");
}

printline();
System.out.print("\"STRING\"" + ".toString() "+ " == \"STRING\""+":>");
if ( "STRING".toString() == "STRING") {
System.out.println("\t\t\t Equal");
} else {
System.out.println("\t\t\t Not Equal");
}

printline();
System.out.print("\"STRING\".toString() " + "== \"STRING\".toString()" +":>");
if ( "STRING".toString() == "STRING".toString()) {
System.out.println("\t\t\t Equal");
} else {
System.out.println("\t\t Not Equal");
}

printline();
System.out.print("\"STRING\".trim() " + "== \"STRING\"" +":>");

if ( "STRING".trim() == "STRING") {
System.out.println("\t\t\t Equal");
} else {
System.out.println("\t\t Not Equal");
}
printline();
}
}

OUTPUT


"STRING".toUpperCase()== "STRING":> Not Equal
------------------------------------------------------------------------
"string".toLowerCase()=="string":> Not Equal
------------------------------------------------------------------------
"STRING".concat("") == "STRING":> Equal
------------------------------------------------------------------------
"STRING".replace('I','I') == "STRING":> Equal
------------------------------------------------------------------------
"STRING".substring(0) == "STRING":> Equal
------------------------------------------------------------------------
"STRING".toString() == "STRING":> Equal
------------------------------------------------------------------------
"STRING".toString() == "STRING".toString():> Equal
------------------------------------------------------------------------
"STRING".trim() == "STRING":> Equal
------------------------------------------------------------------------

[This message has been edited by bongadi (edited May 12, 2000).]

Ajith Kallambella
bartender
posted May 12, 2000 09:51 AM             
Bogandi,
Read it again.

If this String object represents an empty character sequence, or the first and last characters of character
sequence represented by this String object both have codes greater than \u0020 (the space character),
then a reference to this String object is returned.

If the string you are operating on has no leading/trailing white space character, you get the reference to the original string itself. This is true for other methods ie., calling toUpperCase() on an uppercase string, or calling toLowerCase on a lower case string.

Does this answer your question?


Ajith

bongadi
greenhorn
posted May 12, 2000 10:03 AM             
Aaaarrrgghhh....
I got it thanks . I missed greater than \u0020 .

One rant....

(" String ".trim() == "String")
and
("String".trim() == "String")

look quite indistinguishable ... so people please use
proper tags like ..


(" String ".trim() == "String")

quote:
Originally posted by Ajith Kallambella:
Bogandi,
Read it again.
[b]
If this String object represents an empty character sequence, or the first and last characters of character
sequence represented by this String object both have codes greater than \u0020 (the space character),
then a reference to this String object is returned.

If the string you are operating on has no leading/trailing white space character, you get the reference to the original string itself. This is true for other methods ie., calling toUpperCase() on an uppercase string, or calling toLowerCase on a lower case string.

Does this answer your question?


Ajith[/B]


Deepa
unregistered
posted May 12, 2000 10:48 AM           
Thanks maha anna.

To conclude, For the first one it returns true because
toString returns string representationn of the object "string" which is a literal "string". But the literal "string" is already present in the literal pool so it returns true. Pl correct me.

The 2nd one returns false because trim returns a differenet reference.

maha anna
bartender
posted May 12, 2000 11:22 AM             
See you read Maha's mind. . Maha's previous post didn't satisfy you. Isn't?

case 1
I felt may be what you said is as such correct. But that's not the whole reason for the toString() for the first case returning true. To be precise,

the toString() returns the SAME reference of the String object on which the toString() method is invoked on. The String object can be anywhere. It does not matter. It can be in the String pool or in the heap. As long as you compare the result of the toString() with the SAME ref of the object on which you invoked the toString() method , the comparision WILL be true.

In other words
"Deepa".toString("Deepa") is TRUE

as well as

String deepaStr = new String("Deepa");
if (deepaStr.toString() == deepaStr ) is ALSO TRUE.
[ note :case 2 in the above sample code ]

Have you got the very small point which you missed. (may be maha thought that you missed ) This is the reason I didn't stress this in the previos post.

case 2
The trim() method trims all extra chars which have decimal value 0... 32 (\u0000 to \u0020 ) at BOTH ENDS of the invoked String and returns a new String object in the heap if and only if , in fact it really trimmed anything at all. So as long as the trim() method doesn't trim anything the SAME String object's ref is returned.

In the 2nd case Since "String ".trim(), trims one trailing space, it returns a new String object in the HEAP and so the result is false.

Also note that trim() not only trims the space char, it also trims ALL control chars which fall bet 0 to 32 decimal value.

See the foll example. The result is fail



String str1 = "\u0000\u0001ABCD";
if(str1.trim() == str1)
System.out.println("Pass");
else
System.out.println("Fail");



regds
maha anna

[This message has been edited by maha anna (edited May 12, 2000).]

Ihor Strutynskyj
greenhorn
posted May 12, 2000 11:24 AM             
Bogandi: Your code has some bugs. The toLowerCase() printout is used with toUpeerCase(), that's first. The second is I do not understand how you got "STRING".toUpperCase()=="STRING" to be false. After I corrected your code and run it with JDK 1.2.2 I got:
code:
public class AQuestion {
public static void printline() {
System.out.println("------------------------------------------------------------------------");
}
public static void main(String args[]) {
System.out.print("\"STRING\""+".toUpperCase()"+"==" +" \"STRING\""+":>");
if("STRING".toUpperCase() == "STRING") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"string\""+".toLowerCase()" +"==" +"\"string\""+":>");
if("\"string\"".toLowerCase() == "\"string\"") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"STRING\""+".concat(\"\")"+" == "+"\"STRING\""+":>");
if ( "\"STRING\"".concat("") == "\"STRING\"") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"STRING\"" + ".replace(\'I\'"+ "," + "\'I\')" + " == "+ "\"STRING\"" + ":>");
if ( "STRING".replace('I','I') == "STRING") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"STRING\"" + ".substring(0)"+" == "+"\"STRING\""+":>");
if ( "STRING".substring(0) == "STRING") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"STRING\"" + ".toString() "+ " == \"STRING\""+":>");
if ( "STRING".toString() == "STRING") {
System.out.println("\t\t\t Equal");
}
else {
System.out.println("\t\t\t Not Equal");
}
printline();
System.out.print("\"STRING\".toString() " + "== \"STRING\".toString()" +":>");
if ( "STRING".toString() == "STRING".toString()) {
System.out.println("\t\t Equal");
}
else {
System.out.println("\t\t Not Equal");
}
printline();
System.out.print("\"STRING\".trim() " + "== \"STRING\"" +":>");
if ( "STRING".trim() == "STRING") {
System.out.println("\t\t\t\t Equal");
}
else {
System.out.println("\t\t\t\t Not Equal");
}
printline();
}
}


and the result is
code:
"STRING".toUpperCase()== "STRING":>                      Equal
------------------------------------------------------------------------
"string".toLowerCase()=="string":> Equal
------------------------------------------------------------------------
"STRING".concat("") == "STRING":> Equal
------------------------------------------------------------------------
"STRING".replace('I','I') == "STRING":> Equal
------------------------------------------------------------------------
"STRING".substring(0) == "STRING":> Equal
------------------------------------------------------------------------
"STRING".toString() == "STRING":> Equal
------------------------------------------------------------------------
"STRING".toString() == "STRING".toString():> Equal
------------------------------------------------------------------------
"STRING".trim() == "STRING":> Equal
------------------------------------------------------------------------


I also want to add about String:
1) == operator compares references to String objects not actual string content;
2) s1.equals(s2) (where s1 and s2 are both String's) compares string content;
3) all the following functions:
trim(),toUpperCase(),toLowerCase(),concat(),replace()
work under the same rule: "if there is nothing to change return reference to itself".
4) there is also interesting function intern() which will make this String interned in the string pool.

Ihor Strutynskyj
greenhorn
posted May 12, 2000 11:25 AM             
Bongadi, sorry I misspelled your name.

bongadi
greenhorn
posted May 12, 2000 12:06 PM             
Thank you thank you thank you Ihor

(1) There are more problems in my code (like
I have used ``\'' escapes where I should
not have.

(2) I found why "STRING".toUpperCase()=="STRING"
is false.

See at work we have to use older JDK (for some compatibility
reasons). I was using java version "1.1.8" this caused the
following...


"STRING".toUpperCase()== "STRING":> Not Equal
------------------------------------------------------------------------
"string".toLowerCase()=="string":> Not Equal
------------------------------------------------------------------------

After changing my JDK to 1.2 (I have a small script which
switches the links) [ Solaris VM (build Solaris_JDK_1.2.1_03, native threads, sunwjit) ] I got the results that you are getting.

I am still a bit zoned by the discovery though. Will do more
investigation later.


quote:
Originally posted by Ihor Strutynskyj:
Bongadi, sorry I misspelled your name.

No problems
Thanks and regards.
BonGadi

[This message has been edited by bongadi (edited May 12, 2000).]

Deepa
unregistered
posted May 12, 2000 12:52 PM           
Thanks maha anna & others for a detailed explanation.
deepa

rahul_mkar
ranch hand
posted May 12, 2000 10:50 PM             
hi,

thanx everyone. it really helped.

maha anna
bartender
posted May 14, 2000 03:10 AM             
Sameet,
This is to reply Sameet's post in a unrelated thread here. I think you, by mistake posted it there. I am replying here so that we will have all related replies to a particular post in one place.

Regarding your post, yes. what you say is correct. All String literals created with double quotes like this
String deepaLowercaseStr = "deepa";
are created in the String pool. So at run time when you try to intern the deepaLowerCaseStr by deepaLowerCase.intern() it will return the SAME object ref at the pool.

Also one more point to be aware of. The intern() method means you are trying to put this object into the String pool. Which means if there WOULD HAVE been already one literal object in the pool, then NO NEW String object is created in the pool. ONLY ONE copy of distinct objects will be there in the String pool.

So if there WOULD HAVE BEEN no already existing string literal, which has the SAME content as this String object which is trying to intern() now, then a new String literal is created and this fresh created ref at the pool is returned now.

As a follow up , if you try to intern() , an already interned String, the 2nd time,now what happens? Since ONLY one copy can be in the String pool, the String literal's ref (which is created by means of the first intern() action of this String object) is returned now. This 2nd intern() WILL NOT create a one more new String literal in the pool.

As a note to this String literal in the String pool is not covered by the SCJP2 Exam. Since Sameet was so interested in knowing these details I am replying this. The foll. code is an example for the above said info. I took care NOT to have an already existinf "deepa" in the String pool. In other words, I created the deepaLowercase String by uppercasing deepaUppercaseStr and not like "deepa". (not quite correct word uppercasing )

Does this satisfy you Sammet?


The output is Pass17

regds
maha anna


public static void main(String[] args) {
String deepaUppercaseStr = new String("DEEPA");
String deepaLowercaseStr = deepaUppercaseStr.toLowerCase();

if(deepaLowercaseStr.intern() == deepaLowercaseStr.intern())
System.out.println("Pass17");
else System.out.println("Pass17 failed");
}

[This message has been edited by maha anna (edited May 14, 2000).]

Sameet
unregistered
posted May 16, 2000 09:51 AM           
Thankyou Maha Anna for rightly placing my reply.
thank u once again for letting me knpow that intern is not a par t of SCJP exam, i also tried the peice of code that you have given it works fine. Only one copy of given string can exist in the String pool .

regards sameet

|