How can "1" != "1"

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • SammyB
    Recognized Expert Contributor
    • Mar 2007
    • 807

    How can "1" != "1"

    I'm trying to keep up with you youngsters, so I'm taking a beginning Java course. As part of a homework assignment, we were to prompt the user for a number between 1 & 3. We also used while loops in the chapter, so I decided to put the prompt in a while loop to force the user to enter 1, 2 or 3. I was very surprised when it did not work, so I have written a 5-liner to show you the problem:
    [code=java]
    import javax.swing.JOp tionPane;
    public class Weird {
    public static void main(String[] args)
    {
    String s = "";
    while (s != "1" && s!= "2" && s!= "3")
    {
    s = JOptionPane.sho wInputDialog(nu ll, "Enter 1, 2 or 3");
    if (s == null) break;
    }
    if (s!= null) JOptionPane.sho wMessageDialog( null, s);
    }
    }
    [/code]
    I fixed the problem by parsing the string and testing for integers 1, 2, or 3, but the above code should work! The same code in VB works great:
    [code=vb]
    Sub NotWeird()
    Dim s As String
    Do While (s <> "1" And s <> "2" And s <> "3")
    s = InputBox("Enter 1, 2 or 3")
    Loop
    MsgBox s
    End Sub
    [/code]
    Looking at the Java code in the debugger, after the user enters 1, the debugger says s = "1" So far, great, but if I inspect s != "1", it says "s != "1"" = true

    What is this crazyness?!?
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    #2
    Here's a secret:

    When you say

    [CODE=java]String myStr;[/CODE]

    myStr isn't actually a String. Java tries to trick you into thinking it is (and trust me, that is good for a beginner!), but it's not. myStr is secretly a pointer. Basically, myStr holds an address somewhere in memory. That address is where your actual String is. So when you try and compare myStr to something else with == or !=, you're trying to compare the memory address with a String. So "1" != "1", because the String you use as the left hand side is in a different memory location than the "1" on the right side.

    The people at Sun realized this, so they gave you a friendly little method in String called .equals(). So replace

    [CODE=java]myStr == "otherStr"[/CODE]

    with

    [CODE=java]myStr.equals("o therStr")[/CODE]

    Comment

    • SammyB
      Recognized Expert Contributor
      • Mar 2007
      • 807

      #3
      That's insane! But, very vital to know. It's interesting that
      Code:
      String s = "1";
      if (s == "1")
      	MessageBox.Show("C# is not weird!");
      else
      	MessageBox.Show("C# is as weird as Java!");
      string comparisons work in C# but not in Java. Thanks for your help, now I'll have to rewrite my homework like I wanted to in the first place!

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        Originally posted by SammyB
        That's insane! But, very vital to know. It's interesting that
        Code:
        String s = "1";
        if (s == "1")
        	MessageBox.Show("C# is not weird!");
        else
        	MessageBox.Show("C# is as weird as Java!");
        string comparisons work in C# but not in Java. Thanks for your help, now I'll have to rewrite my homework like I wanted to in the first place!
        As a matter of fact the above might work. Literal Strings are stored in an 'intern'
        pool and both "1" strings are stored only once in that pool; that makes your if-
        clause succeed while you actually did it all wrong ;-)

        kind regards,

        Jos

        ps. it's not 'insane'; it just doesn't work your prejudiced mind thought it should work.

        Comment

        • SammyB
          Recognized Expert Contributor
          • Mar 2007
          • 807

          #5
          Originally posted by JosAH
          ... it's not 'insane'; it just doesn't work your prejudiced mind thought it should work.
          not prejudiced :D I just expect the compiler to say :You don't want to do this, Sam!" At a minimum, it could have said "Illegal Indirection, like C++. ROFL --Sam

          Comment

          • JosAH
            Recognized Expert MVP
            • Mar 2007
            • 11453

            #6
            Originally posted by SammyB
            not prejudiced :D I just expect the compiler to say :You don't want to do this, Sam!" At a minimum, it could have said "Illegal Indirection, like C++. ROFL --Sam
            The compiler can't say that because it's perfectly legal to compare two pointers,
            or 'references' as Java calls them; it two pointers compare equal both pointers
            point to the same object.

            For strings you don't want to compare pointers, you want to compare the *value*
            of two (or one?) String object and the String class implements an 'equals' method
            for that:

            [code=java]
            String s1= new String("foo");
            String s2= new String("foo");
            if (s1 == s2)
            System.out.prin tln("s1 and s2 point to same object");
            else if (s1.equals(s2))
            System.out.prin tln("s1 and s2 have equal value");
            else
            System.out.prin tln("s1 and s2 are different");
            [/code]

            In C++ the overloaded '==' operator in the string class takes care of the 'equals'
            functionality. Java doesn't have user defined overloaded operators.

            kind regards,

            Jos

            Comment

            • Dököll
              Recognized Expert Top Contributor
              • Nov 2006
              • 2379

              #7
              Originally posted by SammyB
              I'm trying to keep up with you youngsters, so I'm taking a beginning Java course. As part of a homework assignment, we were to prompt the user for a number between 1 & 3. We also used while loops in the chapter, so I decided to put the prompt in a while loop to force the user to enter 1, 2 or 3. I was very surprised when it did not work, so I have written a 5-liner to show you the problem:
              [code=java]
              import javax.swing.JOp tionPane;
              public class Weird {
              public static void main(String[] args)
              {
              String s = "";
              while (s != "1" && s!= "2" && s!= "3")
              {
              s = JOptionPane.sho wInputDialog(nu ll, "Enter 1, 2 or 3");
              if (s == null) break;
              }
              if (s!= null) JOptionPane.sho wMessageDialog( null, s);
              }
              }
              [/code]
              I fixed the problem by parsing the string and testing for integers 1, 2, or 3, but the above code should work! The same code in VB works great:
              [code=vb]
              Sub NotWeird()
              Dim s As String
              Do While (s <> "1" And s <> "2" And s <> "3")
              s = InputBox("Enter 1, 2 or 3")
              Loop
              MsgBox s
              End Sub
              [/code]
              Looking at the Java code in the debugger, after the user enters 1, the debugger says s = "1" So far, great, but if I inspect s != "1", it says "s != "1"" = true

              What is this crazyness?!?
              Oh! It's crazy alright! Its' quite the headache...

              I also find Java sometimes gives you an error on a line, highlights the line, as result of modifications to completely different lines in the code. And of course the moment I put things back where they belong, Java's happy again...

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                Originally posted by Dököll
                Oh! It's crazy alright! Its' quite the headache...

                I also find Java sometimes gives you an error on a line, highlights the line, as result of modifications to completely different lines in the code. And of course the moment I put things back where they belong, Java's happy again...
                Read my reply #6 for an explanation of this 'crazyness'.
                About those errors on 'unrelated' lines: your modifications have ruined the structure
                of your program then and the compiler can only detect it when the rest of the
                structure of your program can't make sense anymore which may be (many) lines
                from where you made your mistake.

                kind regards,

                Jos

                Comment

                • Dököll
                  Recognized Expert Top Contributor
                  • Nov 2006
                  • 2379

                  #9
                  Originally posted by JosAH
                  The compiler can't say that because it's perfectly legal to compare two pointers,
                  or 'references' as Java calls them; it two pointers compare equal both pointers
                  point to the same object.

                  For strings you don't want to compare pointers, you want to compare the *value*
                  of two (or one?) String object and the String class implements an 'equals' method
                  for that:

                  [code=javascript]
                  String s1= new String("foo");
                  String s2= new String("foo");
                  if (s1 == s2)
                  System.out.prin tln("s1 and s2 point to same object");
                  else if (s1.equals(s2))
                  System.out.prin tln("s1 and s2 have equal value");
                  else
                  System.out.prin tln("s1 and s2 are different");
                  [/code]

                  In C++ the overloaded '==' operator in the string class takes care of the 'equals'
                  functionality. Java doesn't have user defined overloaded operators.

                  kind regards,

                  Jos
                  Good heavens JosAH!

                  Java IS like JavaScript a lot of repect then. I cannot recall how I wrote this but in a previous reply specific to Sammy's scenario, I wondered whether:

                  [CODE=JAVA]

                  Var s1 ="Something"
                  Var s2 ="Something"

                  If (s1 == s2) Then
                  This is good stuff
                  Else
                  MsgBox ("Blaze blaze")
                  End If
                  ...

                  [/CODE]

                  Mind you, I am missing brackets there, but does above signify the similarities in both languages, and if this is a fact, can I look to JavaScrip to get a better understanding of Java, of course to some degree?
                  Last edited by Dököll; Oct 15 '07, 12:54 AM. Reason: respective language noted...

                  Comment

                  • SammyB
                    Recognized Expert Contributor
                    • Mar 2007
                    • 807

                    #10
                    Originally posted by Dököll
                    Good heavens JosAH!

                    Java IS like JavaScript a lot of repect then. I cannot recall how I wrote this but in a previous reply specific to Sammy's scenario, I wondered whether:

                    [CODE=JAVA]

                    Var s1 ="Something"
                    Var s2 ="Something"

                    If (s1 == s2) Then
                    This is good stuff
                    Else
                    MsgBox ("Blaze blaze")
                    End If
                    ...

                    [/CODE]

                    Mind you, I am missing brackets there, but does above signify the similarities in both languages, and if this is a fact, can I look to JavaScrip to get a better understanding of Java, of course to some degree?
                    But, as Jos pointed out above, this will print good stuff in Java also because s1 and s2 are both pointing to the same string.

                    Run the following and see if it helps!
                    [code=java]
                    import javax.swing.JOp tionPane;
                    public class Weird
                    {
                    public static void main(String[] args)
                    {
                    String s1 ="Something" ;
                    String s2 ="Something" ;
                    if (s1 == s2)
                    JOptionPane.sho wMessageDialog( null, "You just think this is good stuff");
                    else
                    JOptionPane.sho wMessageDialog( null, "Blaze blaze");
                    s2 ="Something else";
                    s2 = s2.substring(0, 9);
                    if (s1 == s2)
                    JOptionPane.sho wMessageDialog( null, "This is not expected");
                    else
                    JOptionPane.sho wMessageDialog( null, "Blaze blaze");
                    if (s1.equals(s2))
                    JOptionPane.sho wMessageDialog( null, "Jos is always right!");
                    else
                    JOptionPane.sho wMessageDialog( null, "Why bother with this message!");

                    }
                    }
                    [/code]

                    Comment

                    • Dököll
                      Recognized Expert Top Contributor
                      • Nov 2006
                      • 2379

                      #11
                      Originally posted by SammyB
                      But, as Jos pointed out above, this will print good stuff in Java also because s1 and s2 are both pointing to the same string.

                      Run the following and see if it helps!
                      [code=java]
                      import javax.swing.JOp tionPane;
                      public class Weird
                      {
                      public static void main(String[] args)
                      {
                      String s1 ="Something" ;
                      String s2 ="Something" ;
                      if (s1 == s2)
                      JOptionPane.sho wMessageDialog( null, "You just think this is good stuff");
                      else
                      JOptionPane.sho wMessageDialog( null, "Blaze blaze");
                      s2 ="Something else";
                      s2 = s2.substring(0, 9);
                      if (s1 == s2)
                      JOptionPane.sho wMessageDialog( null, "This is not expected");
                      else
                      JOptionPane.sho wMessageDialog( null, "Blaze blaze");
                      if (s1.equals(s2))
                      JOptionPane.sho wMessageDialog( null, "Jos is always right!");
                      else
                      JOptionPane.sho wMessageDialog( null, "Why bother with this message!");

                      }
                      }
                      [/code]
                      I must have missed a step or two but I was stuck in what seemed to be an endless loop, should I get pop ups to enter stuff, should I have pressed ok for in pop up with "{ }" in the box?

                      Comment

                      • SammyB
                        Recognized Expert Contributor
                        • Mar 2007
                        • 807

                        #12
                        Originally posted by Dököll
                        I must have missed a step or two but I was stuck in what seemed to be an endless loop, should I get pop ups to enter stuff, should I have pressed ok for in pop up with "{ }" in the box?
                        Copy and paste into Weird.java & run it. You get three popups:
                        You just think this is good stuff
                        Blaze blaze
                        Jos is always right!

                        Comment

                        • praveenkumarvpk
                          New Member
                          • Oct 2007
                          • 22

                          #13
                          Hey you can write the code using the String Methods.

                          Here is the code which i modified.

                          while (!s.equalsIgnor eCase("1") && !s.equalsIgnore Case("2") && !s.equalsIgnore Case("3"))

                          {

                          s = JOptionPane.sho wInputDialog(nu ll, "Enter 1, 2 or 3");

                          if (s == null) break;

                          }

                          Comment

                          Working...