3

Possible Duplicate:
Java String.equals versus ==

I thought this would be a neat way of structuring a picker method but the output is not going to the first two if statements and only outputs the last

    public int myPickerMethod(){

        System.out.println("please select from the options ");
        System.out.println("please select 1 for option 1 ");
        System.out.println("please select 2 please select 2 for option 2");
        String input = keyboard.readLine();
        System.out.println("input = " + input);     

        if(input=="1"){

                return 1;
        }
        else if(input=="2"){
            return 2;
        }
        else{
            return 42;
        }
   }

Here is my result from the terminal:

   please select from the options 
   please select 1 for option 1 
   please select 2 please select 2 for option 2
   1
   input = 1
   response = 42

Same goes if I put 2 in. the "response" print statement is the output from the method from a print statement in the main class.

I have not tried this way before but I figured it should work. I don't really get why it isn't. Anyone able to clear this up? Thanks

Community
  • 1
  • 1
Magpie
  • 607
  • 2
  • 7
  • 26

6 Answers6

9

In Java you need to compare Strings using the equals method:

if ( input.equals("1") ) {
    // do something...
}

Since Java 7, you can use Strings in switch statements too:

switch ( input ) {

    case "1":
        // do something...
        break;

    case "2":
        // do something...
        break;

}

Edit: Complementing my answer, here is an example of a class that uses switch with strings and the disassembled code of the class (using javap -c) and why it works (labels 8 and 11).

Foo.java

public class Foo {

    public static void main( String[] args ) {

        String str = "foo";

        switch ( str ) {

            case "foo":
                System.out.println( "Foo!!!" );
                break;

            case "bar":
                System.out.println( "Bar!!!" );
                break;

            default:
                System.out.println( "Neither Foo nor Bar :(" );
                break;

        }

    }

}

Disassembled Foo.class code:

Compiled from "Foo.java"
public class Foo {
  public Foo();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String foo
       2: astore_1      
       3: aload_1       
       4: astore_2      
       5: iconst_m1     
       6: istore_3      
       7: aload_2       
       8: invokevirtual #3                  // Method java/lang/String.hashCode:()I  << hashCode here! (I wrote this!)
      11: lookupswitch  { // 2

                 97299: 50                  // 97299: hashCode of "bar" (I wrote this!)

                101574: 36                  // 101574: hashCode of "foo" (I wrote this!) (yep, they where swaped. the lesser hashCode first)
               default: 61
          }
      36: aload_2       
      37: ldc           #2                  // String foo
      39: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      42: ifeq          61
      45: iconst_0      
      46: istore_3      
      47: goto          61
      50: aload_2       
      51: ldc           #5                  // String bar
      53: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      56: ifeq          61
      59: iconst_1      
      60: istore_3      
      61: iload_3       
      62: lookupswitch  { // 2

                     0: 88

                     1: 99
               default: 110
          }
      88: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      91: ldc           #7                  // String Foo!!!
      93: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      96: goto          118
      99: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
     102: ldc           #9                  // String Bar!!!
     104: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     107: goto          118
     110: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
     113: ldc           #10                 // String Neither Foo nor Bar :(
     115: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     118: return        
}

One interesting thing is that another switch is created (label 62) with integers and is it which do the "real work".

davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
  • +1 for the Java 7 note. I didn't know. What happens under the hood? `equals` of hashing. I think hashing because, switch historically wants an `int`. – Martijn Courteaux Jul 23 '12 at 18:05
  • 1
    Yep, the compiler changes the switch, calling the hashCode method in the switch and cases values :D – davidbuzatto Jul 23 '12 at 18:06
  • 1
    @MartijnCourteaux: I complemented my answer with some disassembled code. Take a look! – davidbuzatto Jul 23 '12 at 18:29
  • I never fully understood the output of javap, but am I right that it first uses a hashCode, used in the first switch, and then rechecks for hashcollisions with `equals`, to be 100% sure that the strings are equal. And finally uses the output of the double check in the second switch. – Martijn Courteaux Jul 23 '12 at 22:32
5

1. Use .equals to compare Objects in java, and String is an Object in Java.

eg: if(input.equals("1"))

2. This is optional, but it will be also good, if you try to use Scanner class.

eg:

Scanner scan = new Scanner(System.in);
String input = scan.nextLine();

3. Its will be also advisable to use switch statement instead of if-else ladder, if switch is used using String then you must have jdk 1.7 or above, else if you are using jdk version less than 1.7, then you can convert the String to character and then use it in switch.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
5

For testing Object (non-primitive type) equality, use Object.equals().

if(input.equals("1")) {

    return 1;
}

The == operator checks whether the references to the objects are equal. A test for reference equality is done within the String.equals() method, among other checks. Below is the Java source for the String.equals() method:

public boolean equals(Object anObject) {
     if (this == anObject) {      // Reference equality
         return true;
     }
     if (anObject instanceof String) {
         String anotherString = (String)anObject;
         int n = count;
         if (n == anotherString.count) {  // Are the strings the same size?
             char v1[] = value;
             char v2[] = anotherString.value;
             int i = offset;
             int j = anotherString.offset;
             while (n-- != 0) {
                 if (v1[i++] != v2[j++])        // Compare each character
                     return false;
             }
             return true;
         }
     }
     return false;
}
Chris Dargis
  • 5,891
  • 4
  • 39
  • 63
  • Ah thanks for clarifying why it was. I was starting to suspect it might be something to do with the String not being primative. – Magpie Jul 23 '12 at 18:03
3

Don't compare value of Strings (or any Objects) by ==. Use equals method like if(input.equals("1")).

== is used to check if references contains same object for example

Integer i1=new Integer(1);
Integer i2=new Integer(1);
Integer i3=i1;
//checking references
System.out.println(i1==i2);//false
System.out.println(i1==i3);//true

//checking values
System.out.println(i1.equals(i2));//true
System.out.println(i1.equals(i3));//true
Pshemo
  • 122,468
  • 25
  • 185
  • 269
3

Object comparison should be .equals not == and String is an object.

input=="1" should be input.equals("1")

EDIT Following always works even though you use ==because they are literals and java allocates same memory location.

 String s ="Hi";
 String s1= "Hi";

 if(s==s1)
 {
     System.out.println("Yes they are same");
 }

But, when we are reading two separate strings (new String()), unless you override equals and hashcode, equality condition may not be satisfied. Read above link for more details.

kosa
  • 65,990
  • 13
  • 130
  • 167
  • thanks that worked. Why is that though? I have found it worked before I tried to use with a string. – Magpie Jul 23 '12 at 18:00
  • When you are comparing on same reference (or) String literals it may work, but in this case they are two separate new strings. – kosa Jul 23 '12 at 18:01
1

Use equals method....

public int myPickerMethod(){

    System.out.println("please select from the options ");
    System.out.println("please select 1 for option 1 ");
    System.out.println("please select 2 please select 2 for option 2");
    String input = keyboard.readLine();
    System.out.println("input = " + input);     

    if(input.equals("1")){

            return 1;
    }
    else if(input.equals("2")){
        return 2;
    }
    else{
        return 42;
    }

}

Akash KC
  • 16,057
  • 6
  • 39
  • 59
  • ah thanks I got it now. +1 though for answering fully. Do you know why it is so that the use of '==' did not work? – Magpie Jul 23 '12 at 18:01
  • "==" compares object reference values where "equals()" compares object contents.... – Akash KC Jul 23 '12 at 18:07