String Equals Java Puzzle

Disclaimer: This is suitable for java beginners only. Some questions are ever green interview questions. Java’s special treatment for String with respect to memory handling is a favourite area for java interviewers. Sometimes we even get bored of this play with String equals. I have written a detailed tutorial on java string and its immutable property, comparing strings and conversion. I think its time interviewers stop asking this question.

Last week a reader sent me the following puzzle and asked me to explain it.

 public class StringEquals {
 public static void main(String[] args){
 jack();
 jill();
 }
 public static void jack() {
 String s1 = "hill5";
 String s2 = "hill" + "5";
 System.out.println(s1==s2);
 }
 public static void jill() {
 String s1 = "hill5";
 String s2 = "hill" + s1.length();
 System.out.println(s1==s2);
 }
 }

I would classify this as a beginner level puzzle for java. To solve this we need fundamental knowledge on how String is instantiated and memory is allocated for it and that is sufficient. This is not a magnificent puzzle and if you have intermediate java knowledge you may not find it interesting. But still for the betterment of our java beginners and yet again I am writing this fundamental article.

Guys by the look of it we know one method is going to return true and another one false. Now lets find out what is the answer and why? When we run the program, jack prints true and jill prints false.


Because, when a string object is instantiated it cross checks with a memory pool if that String is already created. If it is already created then it maps the new variable to the already existing variable. Therefore both these variables are same objects. In jack() at compile time java knows that both the object are same and uses the same instance for referring to it.

In jill, too many things happens. First “hill” is created as a String object, then a new StringBuilder object is created which will help in concatenating two values. After the concatenation is done then it is converted back to a new String object. Real values are known at runtime only.

== operator with respect to String does not checks for the contents of String object. It checks if the compared String object has same reference value or not. Does it point to the same location or not? In jill case, though the value are same the reference is different and so it returns false.

This Core Java tutorial was added on 24/08/2012.

Comments on "String Equals Java Puzzle" Tutorial:

  1. Mario Guerrero says:

    trick and track :)

  2. Anonymous says:

    Nice.. thanks.

  3. Anonymous says:

    Gud explanation for beginners.

  4. ravi says:

    what is the java command to print this information..

  5. Anonymous says:

    Good one…

  6. Shashi Kanth says:

    Great.
    It’s not only for beginners.
    How to print this Code.

  7. Deepesh Uniyal says:

    Interesting Joe..
    Thanks such a nice explanation …

  8. syed says:

    Nice thought….

    Well done,……

    Thanks.

  9. chi.. says:

    Thanks ….

  10. Padma says:

    nice explanation. Can u explain a little more about String pool??

  11. Anonymous says:

    well explained.. thank you

  12. Sethu says:

    Joe the interesting piece was the inner stack trace you have displayed.
    Could you please share how to get this.

  13. shiva says:

    nice…..

  14. Joe says:

    Friends,

    javap is a tool that is available as part of JDK and it can be found at JDK_HOME\bin

    It is a java class disassembler.

    Command: javap -c

    prints the disassembled binary code. Using this I got the above information shown as image.

  15. Anonymous says:

    Excellent..as usual

  16. Anonymous says:

    Thanks for lot of information JOE

  17. deepali says:

    marvellous……really joe it is for all begginers and masters..to know these basic concepts….

  18. Subrat says:

    Nice one buddy!!. keep posting ..

  19. Anonymous says:

    you are an excellent java tutor buddy….carry on…thanks

  20. Palanikumar says:

    Respected Sir,

    I am very proud of you sir. your explanations are so super. your example very good.i appreciate your work definitely. if you like i will join with you.

  21. Ted says:

    In method jack(), why isn’t a new object of String “hill” created and then a StringBuilder object help appending the primitive 5, finnally returning a new string?

  22. puneeth says:

    thanks:)

  23. Muthuraj says:

    Thanks Joe :-) very nice explanation….

  24. Shaheda says:

    Hi Joe,

    please wil you elobrate more on how to use java class disassembler!!!

  25. Ritu says:

    Joe
    Please post an article with basic questions of sql or pl/sql asked in interviews.

    Thanks in Advance!!!

  26. Anonymous says:

    Thanks Sir…. Good Job

  27. Himanshu says:

    Nice……. and Thank you

  28. Santosh says:

    Nice article..explains the basic things in a simple yet effective way..

  29. Anonymous says:

    Thank you!!!

  30. cvd says:

    Nice One. Add more post for Java.

  31. Navin says:

    Hi Joe,

    I tried this example by adding some more sout code with the hashcode values.

    —-
    public class StringEquals {
    public static void main(String[] args){
    jack();
    jill();
    }
    public static void jack() {
    String s1 = “hill5″;
    System.out.println(” jack : S1 hashcode”+s1.hashCode());
    String s2 = “hill” + “5”;
    System.out.println(“jack : S2 hashcode”+s2.hashCode());
    System.out.println(s1==s2);
    }
    public static void jill() {
    String s1 = “hill5”;
    System.out.println(“jill : S1 hashcode”+s1.hashCode());
    String s2 = “hill” + s1.length();
    System.out.println(“jill : S2 hashcode”+s2);
    System.out.println(“jill : S2 hashcode”+s2.hashCode());
    System.out.println(s1==s2);
    }
    }

    Output is as below:

    jack : S1 hashcode:99281428
    jack : S2 hashcode:99281428

    true

    jill : S1 hashcode:99281428
    jill : S2 hashcode:99281428

    false

    as == check only the reference and not the content and as i can see that the hashcode reference no is same for both jack and jill s1 and s2 object…then why one is True and one False ….

    Please don’t mind as i am veru beginner of Java and a bit confused with this output..

    Thanks for your effort :)

  32. Jayesh Mehta says:

    Yes previous question has to be answered. It is really making in confuse.

  33. Anonymous says:

    @Navin and @Jayesh…as shown in your example the values are same as also indicated by the hashcode but note that the “==” operator on strings checks for the memory locations and not for the values… in jack both the concatenations are on string itself but in jill the concatenation is on a string and a primitive number(int) so a stringbuilder will be used to concat and it returns a string object pointing to a new memory location…

  34. Anish Dubey says:

    can you plz tell me how to use print functions for the task like,to get print out by printer?

  35. kuntal chakrabarti says:

    Like your previous articles, this is also great..Expecting more and more articles like this..

  36. Anonymous says:

    Hi Joe,

    I still could not get the point why the references are not pointing t the same object in Jill’s case.I mean its hill5 only right,In both the cases?

    Please put some light on this.

    Thanks

  37. Jiji says:

    Java has to determine if its the same string during the compile time. In jill() its creating the string during run time and its creating a new object in the heap. The hashcode for both the objects are the same because of the hashcode and the equals contract. If the equals() method evaluates to true (in our case it is) then the hashcode should be the same.

  38. Mubarak Ali says:

    Excellent…Thanks for your efforts.

  39. Anonymous says:

    how to edit a class file and recompile in java?

    Thanks

  40. Sigamani says:

    Can u pls tell me how to print this class ???

  41. chandra says:

    What happens when we use s1.equals(s2); In both the jill and jack functions.

  42. ayushi says:

    thanx a lot!!

  43. shashwat says:

    if in jack method i am using
    s2=”hill”+5 then result is true

    if int i=5
    s2=”hill”+i then its true.

    Why?

  44. shankardayal says:

    why the other operators EXCEPT ‘+’ are not used in STRING MANIPULATION?

  45. Rakesh says:

    hey Joe,

    Very nice article, Thanks for sharing.
    Its always a matter of confusion for beginners “checking strings”.

    @Navin and @Jayesh

    If you read the equals contract in Object class, it clearly specified that if two objects are equal then their hashCode has to be same but if two Objects have same hashCode then its not meant that they are equal.

    Hope this will clear your doubts.

  46. Rakesh says:

    @shashwat

    why – here is the answer.

    you have concatenated an integer with a String, so the compiler has to use a String Builder for this, see Joe’s disassembled code.
    Now the location of the resultant string after concatenation changed and the == check only the memory location, that’s why a false is returned.

    Hope this will clear your doubt.

    ~cheers
    Rakesh

  47. Nivy says:

    @Rakesh-
    You have not understood the Shashwat’s doubt.
    His actual doubt is – in both cases concatenation is happening ,then why in Jill() only new string object is created in heap space.

    Please help me with same.
    am very much clear with == and equals.

  48. Anonymous says:

    @shashwat

    probably its because for “hill” + 5 at complie time it is calculated and s2.length at run time.

    @joe @rakesh correct me if I am wrong.

    my query.

    Why at run time StringBuilder is needed and how at compile time the reference is matched

  49. Rohit Saxena says:

    @Shashwat

    First of all int i = 5; s2 = “hill” +i; s1==s2 will give you false.

    Reason is for constants/literals and final variables the concatenation is done at complie time, no StringBuffer s1==s2 true.

    But if any of the piece is a variable like “hill” + i; the concatenation is done at run time using StringBuilder.

    new StringBuilder(“hill”).append(i);

  50. Satish says:

    That is amazing article. When you say ‘it is for beginners’ Joe, what is there for intermediate and advanced users?

  51. Kedarr says:

    To achieve both functions true. you may use following program.
    public class StringEquals {
    public static void main(String[] args){
    jack();
    jill();
    }
    public static void jack() {
    String s1 = “hill5”;
    String s2 = “hill” + “5”;
    System.out.println(s1==s2);
    }
    public static void jill() {
    String s1 = “hill5”;
    String s2 = “hill” + s1.length();
    System.out.println(s1.equals(s2));
    }
    }

  52. sneha says:

    very helpful

  53. Aman says:

    In case of string how do you know string are different ,you will say using ‘==’ but if it returns false how to find hashcode,you will say hashcode,Then why hashcode is same but string object is different.
    What is proper way to justify find different object in case of string.please please write the comment joe sir………….I am waiting for your comment.
    Thanks for thos article.

  54. Aman says:

    public class HashCodeDemo {

    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s=new String(“demo”);
    String s1=new String(“demo”);
    System.out.println(s==s1);
    System.out.println(s.hashCode());
    System.out.println(s1.hashCode());
    }

    }
    //output:
    false
    3079651
    3079651
    question :why different object have same hashcode,Is it proper way to classify the different object???

  55. pratyusha says:

    As contents of both objects are same hashcodes are same,== operator checks whether two referrences s,s1 are pointing to the same object or not ,here s,s1 are two different objects so it returns false

  56. Rohit Saxena says:

    Clearing hashCode doubts.

    Hashcode methods only returns an unique integer and as per contract if 2 objects are equal by equals method, then the hashcode must return the same integer.

    Now java.lang.String class overrides hashcode method. Lets see the implementation

    public int hashCode() {
    int h = hash;
    if (h == 0) {
    int off = offset;
    char val[] = value;
    int len = count;

    for (int i = 0; i < len; i++) {
    h = 31*h + val[off++];
    }
    hash = h;
    }
    return h;
    }

    where value is char[] in which the String value is stored.

    It is clear String hashcode returns the hash code value based on the character value of the String following the contract of hashcode.

    Therefore same string returns same hashcode. It does not return the address.

  57. Naga Raju says:

    Hi, what was the version of JDK used to check the byte code ?
    With 1.6 I could see StringBuffer being used instead of StringBuilder in OpenJDK.

    27: ldc #35 // String world1
    29: invokespecial #37 // Method java/lang/StringBuffer.””:(Ljava/lang/String;)V
    32: aload_2
    33: invokevirtual #40 // Method java/lang/String.length:()I
    36: invokevirtual #46 // Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;
    39: invokevirtual #50 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
    42: astore_3
    43: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
    46: aload_3

    >java -version
    java version “1.6.0”
    OpenJDK Runtime Environment (build 1.6.0-b09)

  58. Pawan Ydav says:

    What is difference between String s=”data”; and String s=new String(“data”);?

  59. Rajlaxmi says:

    Hi Joe,

    Its a nice tutorial, but I still have a doubt, please see the code segment below:

    String s1=”abc”;
    String s2=”def”;
    String s3=”abcdef”;
    String s4=new String(“abcdef”);

    s1+=s2;

    System.out.println(s1==s3);
    System.out.println(s3==s4);
    System.out.println(s1==s4);

    Output of this is:
    false
    false
    false

    Could you please explain?

  60. Bala says:

    @ Rajlaxmi

    s1, s2,s3 are referring to string literals created in string pool.
    s4 is referring to a string created in the heap.

    s1+=s2; this creates a new string in the heap and s1 is made to refer this.

    s1==s3 here comparison is happening between the “abcdef” in pool and the “abcdef” in heap.

    the same with s3==s4 and s1==s4.

  61. Anonymous says:

    Great Article…..Good work.

  62. sa says:

    nice one

  63. Santosh says:

    our stroy is kind of same

  64. Gude Sreekanth says:

    Hi sir…really awesome explanation. Now i got a clear idea on strings concept…

  65. shakeera says:

    really nice comments… its cleared so many confusions on strings

  66. Arvind Aggarwal says:

    Dear Joe,

    Thanks a lot for this and your all other articles………….
    I am a old reader of your blog……its really nice one….Your explanation are very close to the INDIAN IT professionals….
    I expect One more favor from you………

    I just want one complete article on String comparison covering all conditions for “==” and “equals” operator to mastermind this concept and evergreen preparation for first interview question of JAVA……

  67. Prabakaran says:

    @Naveen – I tried the same, but i am getting the different hashcode for jill s2.

    jack s1::22772102
    jack s2::22772102
    Jill s1::22772102
    Jill s2::8880493

Comments are closed for this "String Equals Java Puzzle" tutorial.