File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Doubt pertaining to '==' operator Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Doubt pertaining to Watch "Doubt pertaining to New topic
Author

Doubt pertaining to '==' operator

Neha Monga
Ranch Hand

Joined: Mar 13, 2007
Posts: 34
Hello All!

Can anyone pls explain why the first code snippet will print "Equal" and secong code snippet will print "Not Equal"?

1) Read this piece of code -->

if("String".replace('T','t')=="String");
System.out.println("Equal");
else
System.out.println("Not Equal");

Ans --> the code will compile and print "Equal"

2) Read this piece of code -->

if("String".replace('g','G')=="String".replace('g','G'));
System.out.println("Equal");
else
System.out.println("Not Equal");

Ans --> the code will compile and print "Not Equal"

Thanks in advance!

anil kumar
Ranch Hand

Joined: Feb 23, 2007
Posts: 447
Hi

Neha

Welcome to java ranch

--------------------------------------------------------------
if("String".replace('T','t')=="String")//line 1
System.out.println("Equal");
else
System.out.println("Not Equal");
--------------------------------------

at line ther should not be a semicolon.if semicolon is there it will give compile time error.

String replace(char c1,char c2);

If it finds the character c1 you specified in the String and replaces with c2 and returns new refernce to the new String object.If it does not find that c1 it will return the same refernce.

In the first case there no capital T is there.So it returns the same refernce and the == operator checks for equality of refernce.And the "String" is a literal .It will be there in String constant pool.That why you are getting Equal

But in the second case you are checking two different String refernces which are pointing to two different String objects in the heap.


Thanks
Anil Kumar
[ May 21, 2007: Message edited by: anil kumar ]
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

Hi Neha,

First of all you had put a semicolon in both the if statements which will cause a compiler error! ;-)

The javadoc for replace() method in String Class is as follows:


public String replace(char oldChar,char newChar)

Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.

If the character oldChar does not occur in the character sequence represented by this String object, then a reference to this String object is returned. Otherwise, a new String object is created that represents a character sequence identical to the character sequence represented by this String object, except that every occurrence of oldChar is replaced by an occurrence of newChar.



In case of your first set of code,



There is no replacement done because of the srcChar or oldChar 'T' is absent while replacing. So There is *no* New Object created. Instead the same old "String" is returned. Now when you compare the *reference* using "==" opeartor, both of them would be present in the same memory inside the String Literal Pool.

So you get "Equal" for this case 1.

Let's go to Case 2.



As per the javadoc the string is being replaced at both the places because of the srcChar 'g' is present and the result is *Two NEW Objects* created at both the ends of "==" operator and they are checked for *Reference Equivalence*.

As you know about "==" operator, the check on *two different* objects give "Not Equal".

So you get "Not Equal" for Case 2.

Hope it clears.
[ May 21, 2007: Message edited by: Raghavan Muthu ]

Everything has got its own deadline including one's EGO!
[CodeBarn] [Java Concepts-easily] [Corey's articles] [SCJP-SUN] [Servlet Examples] [Java Beginners FAQ] [Sun-Java Tutorials] [Java Coding Guidelines]
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

Oops! I am sorry for making it a seems-to-be-duplicate-reply! [One of the K&B's style i like much ]

Before replying when i saw there were no replies. But by the time i posted there was an entry by Anil Kumar which is same that of mine.

Hope that does not cause an issue!
[ May 21, 2007: Message edited by: Raghavan Muthu ]
Neha Monga
Ranch Hand

Joined: Mar 13, 2007
Posts: 34
Hey Raghav and Anil,

Thanks a bunch for clarifying...its now very much clear to me and sorry for that ';' after 'if'....that was a typo...

thanks again ..
siva prasaad
Greenhorn

Joined: Jan 10, 2007
Posts: 23
Hi Raghavan
I had understood the case 1.

But I think in case 2 ,

"String".replace('g', 'G') will create a String object in literal pool wiht value "StrinG"
The other side of '==' operator also points to same object,since "StrinG" is already there in pool.
So as per my understanding it should goto Case1.

Please clarify me if iam wrong.

code:
--------------------------------------------------------------------------------

if ("String".replace('g', 'G') == "String".replace('g', 'G'))System.out.println("Equal");elseSystem.out.println("Not Equal");


--------------------------------------------------------------------------------

Regards
Siva
anil kumar
Ranch Hand

Joined: Feb 23, 2007
Posts: 447
Hi

siva
----------------------------------------------------------------------------
The other side of '==' operator also points to same object,since "StrinG" is already there in pool.
------------------------------------------------------------------------
"String".replace('g', 'G')

this method return reference to a new String object;


Thanks
Anil Kumar
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

Hi Siva,
I think Anil has answered your query. But still, You can please read the javadoc comments for the replace() method of String class again.

In brief,



Hope this helps.
[ May 21, 2007: Message edited by: Raghavan Muthu ]
siva prasaad
Greenhorn

Joined: Jan 10, 2007
Posts: 23
Hi Raghavan,
I agree with you that replace creates a new object if it is successful.

So in case 2:
As you said replace will create a new string with value "strinG", right.
So as of now one object with value "strinG" is there in String literal pool.

Now after "==" operator , we see the same funtionality of updating the "string" to "strinG".

Now in this case, since already "strinG" is created in the literal pool,
obviously there is no need to create a new string with same value in the pool.
So I think it is pointing to same object.

If this is not the case , then can we assume "Two String objects with same value in the String literal Pool".

Please clarify me.
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

Hi Sivaprasad,


then can we assume "Two String objects with same value in the String literal Pool".


Yes. Thats perfectly right. I would suggest you to please go through Strings Literally, an excellent article given by Corey McGlone.

I am sure after reading this article, you would not have any further doubts with respect to String Objects created in the Heap as well as the String Literal Pool.

Good Luck.
siva prasaad
Greenhorn

Joined: Jan 10, 2007
Posts: 23
Hi Raghavan,

Thanks a lot for the information provided.
Iam now at a better understanding of Strings.
Iam preparing for java1.5 Can you please specify the links for the good articles.

Cheers.
Siva Prasad
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

Hi Sivaprasad,

Thats nice to hear!

If you are directly taking SCJP 5.0, i would suggest you to check this Javaranch CertFaq first!

As of now, i just checked this link for SCJP 5.0 Mock exams. chandra's SCJP 5.0 Mock exams

HtH.
Good Luck for your exam.
[ May 22, 2007: Message edited by: Raghavan Muthu ]
madhu v pe
Ranch Hand

Joined: Apr 21, 2007
Posts: 100
Hi all,

pls look into the below 2 statements

my doubts are as belww
//----part1----//
there are 2 literals in the pool "String" and "StrinG"
when we call replace it creates another literal StrinG places at another location of pool.
so both are in different locations then returns not equal
right?

//----part2----//
there will only one literal "Strng" in pool.
when we call replace should create another literal "String" in seperate location
then both should point to different locations
then it should return not equal.
right?
but in this case it is returning equal.
why?

pls clarify my doubt.

Thanks
[ May 23, 2007: Message edited by: madhu v pe ]
anil kumar
Ranch Hand

Joined: Feb 23, 2007
Posts: 447
Hi

madhu

Before creating the literal,it will check the pool,if that string literal is not there then it creats the new literal and assigns the reference to the reference variable.In your case ,the literal is already there.So it won't create another literal.

see below

String s1="anil";//line 1
String s2="anil"//line 2
String s3="Anil"//line 3

at line 1 String anil is created in pool,after to that at line 2 it won't create another string,Because it is already there.But at line 3 it creats a new String (A is capital here)


Thanks
Anil Kumar
madhu v pe
Ranch Hand

Joined: Apr 21, 2007
Posts: 100
Thanks Anil,

this is ok what you tried to explain.

actually this is the same doubt what siva prasaad asked,
I have read the article provided by Raghavan as a answer to siva prasad,
but I don't see any statement which clarifies my doubt.
don't know what siva prasad made a conclusion for his doubt.

pls bare with me

otherwise can you tell me the sequence of execution in the statement


hope you understand what I am asking pls take my example only
Thanks
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3355

thats fine Madhu. no issues. thats why this forum is here and we are all present..

lets work out..

As you said,



Lets start one by one as you have said in lines...

  • if("String") -> Creates a String ("String") in the String literal pool.
  • "String".replace('g','G')


  • finds the character to replace 'g'
  • replaces the 'g' with 'G' thereby creating a different String "StrinG" in the literal pool
  • Since the replace operation was successful, it creates a new String object in the Heap with the latest content ("StrinG") and returns the newly created object
  • =="StrinG" -> as there is a String present in the Literal pool (as a result of previous step), it does not create any.


  • So at the end you have,
  • Two Strings in Literal Pool - "String" and "StrinG"
  • One Brand new String Object with the content "StrinG"


  • When comparing, if("String".replace('g','G')=="StrinG"), the memory location where the newly created string object ("StrinG") ( which is returned as a result of replace operation) is checked against the memory pointed to by the String "StrinG" (RHS of the ==) in the String Literal Pool.

    Obviously, there wont be any match. Thats why you get Not Equal.

    Does that clear your "part 1"?
    HtH.
    [ May 23, 2007: Message edited by: Raghavan Muthu ]
    madhu v pe
    Ranch Hand

    Joined: Apr 21, 2007
    Posts: 100
    Thanks Raghavan,
    can you explain my part2 also


    Thanks
    Abdul Mohsin
    Ranch Hand

    Joined: Apr 26, 2007
    Posts: 111

    why there is a difference in output

    if("String".replace('g', 'g')=="String")
    System.out.println("equal");
    else System.out.println("not equal");

    output:equals
    ************
    if("String".replace("g", "g")=="String")
    System.out.println("equal");
    else System.out.println("not equal");

    output: not equal


    Regards,

    Abdul Mohsin


    Regards, Abdul Mohsin
    madhu v pe
    Ranch Hand

    Joined: Apr 21, 2007
    Posts: 100
    welcome to this thread Abdul,

    Pls lets finish my doubt. then will concentrate on yours,
    even I too have the same question what you have posted in the queue which needs to be concentrated.
    pls go through the thread , if you can clarify my doubt in your way that is always appreciated.

    and your understanding about my point is also well appreciated.

    Thanks alot.
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3355

    Hi Madhu,

    Coming to your second part ("part 2").


    //----part2----//
    if("String".replace('g','g')=="String")//equal


    As with the explanation for the "part 1" (in the prev reply), except the replacement is done with no real effect. Actually there is no replacement happened. Thereby NO NEW STRING Object is Created and the original String "String" is returned.

    During the comparison of memory addresses, they both are equal.

    Look at the following piece of code.




    When running the above piece of code, the output produced is as follows.



    Look at the first 2 lines.. You can see the hashcode being changed meaning a new object is being created because of the successful replacement.

    Look at the last 2 lines... The hashcode is not changed at all. Means the replacement was not of any effect. So new new object is created here.

    Hope it clears your "part 2".
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3355

    Hi Abdul,

    As per the 1.4.2 API,

    There is only one method replace(char,char) which accepts only two character arguments to replace and to be replaced.

    Probably you might have used replaceAll(String,String) which takes two strings - first one for the regex and the second one for replacement.

    Not sure of this method. Let me check and get back.

    Which version of JDK you use?
    madhu v pe
    Ranch Hand

    Joined: Apr 21, 2007
    Posts: 100
    Thank you very much Raghavan,

    the missing link is
    "// while replacing with the same character - No Effect!"
    i am not aware of this
    thats why I am confused why two are giving different output?
    now I have understood, once again thanks.

    let concentrate on Abdul's question.
    Abdul Mohsin
    Ranch Hand

    Joined: Apr 26, 2007
    Posts: 111

    No I am using 1.5 and there is a method in api

    String replace(CharSequence target, CharSequence replacement)

    Please explain !!!

    Regards,

    Abdul Mohsin
    anil kumar
    Ranch Hand

    Joined: Feb 23, 2007
    Posts: 447
    Hey

    madhu
    ---------------------------------------------------------------------
    the missing link is
    "// while replacing with the same character - No Effect!"
    i am not aware of this
    thats why I am confused why two are giving different output?
    now I have understood, once again thanks.
    --------------------------------------------------------------------

    String s=new String("String");
    String s1=new String("String");
    System.out.println(s==s1);
    s1=s.replace('g','g');
    System.out.println(s==s1);

    What ever be the case if you apply replace on a string,if that character or a character sequence it finds ,it returns a new reference but again it depends on the string pool.If it finds on the pool it returns the reference
    of the string which already in the pool,otherwise it creates a new object and returns a new reference.

    see the ooutput
    Output is

    false
    true


    Thanks

    Anil Kumar
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3355

    Hi Anil,

    It certainly DOES NOT return a new String and the result is false for both the statements.

    I have checked with your program now and i do get "false" for both the places.

    Can any ranchers clarify on this aspect especially with the replacement of the same character, if we miss out anything?
    anil kumar
    Ranch Hand

    Joined: Feb 23, 2007
    Posts: 447
    Hi

    Raghavan

    I don't know which version you are using ,but i am using jdk 1.5

    i have again checked that i am getting the same output

    And one thing these are statements from java doc
    --------------------------------------------------------------------------
    If the character oldChar does not occur in the character sequence represented by this String object, then a reference to this String object is returned. Otherwise, a new String object is created that represents a character sequence identical to the character sequence represented by this String object, except that every occurrence of oldChar is replaced by an occurrence of newChar.

    ---------------------------------------------------------------------------
    Here they did not say ,that if you replace the same character,you will get the same reference

    false
    true


    Thanks

    Anil Kumar
    [ May 23, 2007: Message edited by: anil kumar ]
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3355

    Hi Anil,

    I do use JDK 1.4.2 version. I myself had copied and pasted the same JavaDoc code in my first reply to this thread.

    I also agree with that. But here i do get "false" for both. How?

    Moreover when i print the hashcode, i get the same hashcode for both (even after the replacing). That means both of them are pointing to the Same String in the Literal Pool. Aint i?

    Is there any difference across the JDK versions in the implementation perspective?

    Please any ranchers clear this doubt
    anil kumar
    Ranch Hand

    Joined: Feb 23, 2007
    Posts: 447
    Hey

    Raghavan
    -------------------------------------------------------------------------
    // To replace with the same character - No Effect!
    String s4 = "Saravanan";
    System.out.println("hashcode of s4 is :"+s4.hashCode()+", s4="+s4);s4 = s4.replace('S','S');
    System.out.println("hashcode of s4 after replace is :"+s4.hashCode()+", s4="+s4);
    -------------------------------------------------------------------------

    I have clearly mentioned in all my previous posts.That it depends on STRING CONSTANT POOL.In your case the Sarvanan is already there in the String constant pool.In the second replace the you are replacing S and the String you will get is same and it checks that literal in the pool if it finds it assigns that reference ,in your case it finds .
    That's why you got the o/p like that.


    Thanks
    Anil Kumar
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3355

    Hi Anil,

    I do definitely agree and i have been also conveying the same information. But if you look at the main objective of the post, it says the same.



    I think it indicates the replacement of the character 'g' with itself. Before replacing, obviously there should have been a String Constant "String" in the Literal Pool. Aint I?

    In that case only, there is no new object getting created and thereby the same object is returned resulting "true" in the if loop test.

    Look at your code once again,



    Line 1 & 2:
    As you are invoking * new * operator, it does not matter it will create two new String Objects. Aint I?

    Line 3:
    As usual, the references of two different objects (because they are created using *new*) will not match. So you get a false here!

    Line 4:
    At line 4, you are trying to do a replace in the String object "s". As it can find the character to replace 'g' (first one) and replaces, but its of no use. Means, its doing the operation on the same String which effectively serves no real purpose. This is what i was telling that NO NEW OBJECT IS CREATED and THERE IS NO EFFECT!

    Probably, i will withdraw my statement saying "No replacement is done!". I should have added a clause like "No Effective Replacement happening"!

    In such scenario, the result of s.replace('g','g') will give the same String which is originally pointed to by "s" - means the same old "S" only. As there is no new object created, no new memory as well.

    Line 5:
    But ultimately, when you assign the reference s to s1, both of them should point to the same object leaving the original object pointed by s eligible for GC. In this case, "true" seems to be correct!

    But then how come i do get "false" when i execute? Only difference is the JDK versions between we both.

    Here is where i have the doubt and expect some expert's reply here

    Thank you!
    [ May 23, 2007: Message edited by: Raghavan Muthu ]
    Sergio Tridente
    Ranch Hand

    Joined: Mar 22, 2007
    Posts: 329

    Just a couple of observations on what have been said

    Originally posted by Raghavan Muthu:
  • if("String") -> Creates a String ("String") in the String literal pool.



  • The "String" literal string is not created at that moment of execution, but rather when the class is loaded.

    Originally posted by Raghavan Muthu:

  • "String".replace('g','G')


  • finds the character to replace 'g'
  • replaces the 'g' with 'G' thereby creating a different String "StrinG" in the literal pool
  • Since the replace operation was successful, it creates a new String object in the Heap with the latest content ("StrinG") and returns the newly created object




  • The "StrinG" string is not created in the literal pool. It is certainly created in the heap, but no reference is added to the string literal pool. Remember: that task is performed when the class is loaded, but not during execution of methods. Then, as you said, a reference to that string object is returned by replace().

    Originally posted by Raghavan Muthu:
  • =="StrinG" -> as there is a String present in the Literal pool (as a result of previous step), it does not create any.



  • Here again, the "StrinG" string literal is not creted "as a result of previous operation" (e.g. during execution of the method). It was created (in the heap) and a reference added to the string literal pool when the class was loaded.

    Please, comment on these statements and mark any error. Thank you.


    SCJP 1.4 (88%) - SCJP 5.0 Upgrade (93%) - SCWCD 1.4 (97%) - SCBCD 5.0 (98%)
    Barry Gaunt
    Ranch Hand

    Joined: Aug 03, 2002
    Posts: 7729
    Since you guys are having so much fun here, take a look at these two:



    Note: the String.intern() method is not in SCJP scope.


    Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
    Getting someone to think and try something out is much more useful than just telling them the answer.
    Abdul Mohsin
    Ranch Hand

    Joined: Apr 26, 2007
    Posts: 111

    Hi Barry,


    Please explain why there is such difference

    if("String".replace('g', 'g')=="String")
    System.out.println("equal");
    else System.out.println("not equal");

    output:equals
    ************

    if("String".replace("g", "g")=="String")
    System.out.println("equal");
    else System.out.println("not equal");

    output: not equal


    Regards,

    Abdul Mohsin
    Sergio Tridente
    Ranch Hand

    Joined: Mar 22, 2007
    Posts: 329

    Originally posted by Raghavan Muthu:
    Moreover when i print the hashcode, i get the same hashcode for both (even after the replacing). That means both of them are pointing to the Same String in the Literal Pool. Aint i?


    Be careful with String.hasCode(). It does not represent what you think. Accordingly to the javadoc:
    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]
    using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)


    This value has nothing to do with the internal address of the object (this is tipically the case with implemenations of the Object class).
    Faisal Ahmad
    Ranch Hand

    Joined: Aug 31, 2006
    Posts: 355

    Originally posted by Barry Gaunt:
    Since you guys are having so much fun here, take a look at these two:



    Note: the String.intern() method is not in SCJP scope.


    Output:
    true
    true

    If I am not wrong, in the above tests, only ONE String object(StrinG) is returned. No new objects are created. That's because we are using intern(). So, finally, the comprisons are made between the same "StrinG" always!
    Thanks Barry, I've learnt something new!
     
    Don't get me started about those stupid light bulbs.
     
    subject: Doubt pertaining to '==' operator