3

When I run some code (Shown later), I tell it to check if the string == "1", if it is, output "It's 1!", else, output the string.

Code:

double shirt3 = Math.random() * 9;
String shirt2 = Double.toString(shirt3);
char shirt1 = shirt2.charAt(0);
String shirt = Character.toString(shirt1);

if(shirt == "1") {
    System.out.println("It's 1!");
} else {
    System.out.println(shirt);
}

Output:

7
4
8
1
7
1
7
7
6
0

2

6 Answers 6

9

You need to use

if (shirt.equals("1"))
    ...

This will compare the actual contents of the String objects, rather than their identities.

Sign up to request clarification or add additional context in comments.

Comments

5

You've made the Java beginner's mistake of using == to test String equality. Use the equals method instead.

The longer explanation is that the == operator in Java tests to see if two object references are identical; i.e. it tests if the left and right operands are the same object. But what you have is two distinct strings that contain the same sequence of characters. They are "equal" strings, but not the same object.

As a general rule of thumb, you should always use equals to compare strings.

(There are some situations where == will work, but you really need to understand what you are doing to be sure. And its is simply not worth the effort / risk in the vast majority of use-cases.)

Comments

4

To check if two strings are the same in Java, use .equals():

"1" == new String("1") //returns false
"1".equals(new String("1")) //returns true

EDIT: Added new String("1") to ensure we are talking a new string.

1 Comment

Actually, "1" == "1" will return true due to string literals being interned. But if either of those two "1"s isn't a compile-time constant, that's when you'll see the issue.
3

Besides the fact you'll need to use the equals method to compare Strings in java

// it't allways a good idea to use constant.equals(...)
// to avoid possible NullPointerExceptions
if ("1".equals(shirt))
    ...

in your case you don't have to convert your character into a String you can also compare single characters. Does the same without creating an additional String object and you don't have to deal with the equals method.

if (shirt1 == '1')
        ...

2 Comments

+1 for providing the best solution here: bypassing the re-stringification and the String issues altogether. :)
@cHao - this is the best solution, but it is more important that the OP understand why using == with String is wrong.
2

To compare strings use equals.

if(shirt.equals("1"))
     System.out.println("It's 1!");
    }else{
        System.out.println(shirt);
    }

Comments

1

A more general rule is to not make code more complicated than it need to be.

int shirt = (int)(Math.random() * 10); // shirt numbers from 0 to 9.
if(shirt == 1) 
    System.out.println("It's 1!");
else 
    System.out.println(shirt);

This illustrated that == can be used to compare primitives. It can also be used to compare references, but not to compare the contents of objects.

Double d = 0.1;
Double e = 0.1;
System.out.println("(Double) 0.1 == (Double) 0.1 is " + (d == e));

double x = 0.1;
double y = 0.1;
System.out.println("0.1 == 0.1 is " + (x == y));

prints

(Double) 0.1 == (Double) 0.1 is false
0.1 == 0.1 is true

This shows that when comparing Double, like Strings, objects == doesn't compare contents.

One confusion in all this when a cache is used, as is the case for String literals. This means that values which are referenced in different places actually use the same object for performance reasons.

Integer d = 10;
Integer e = 10;
System.out.println("(Integer) 10 == (Integer) 10 is " + (d == e));

int x = 10;
int y = 10;
System.out.println("10 == 10 is " + (x == y));

prints

(Integer) 10 == (Integer) 10 is true
10 == 10 is true

The first example works because Java 5.0+ uses a cache of small integers. (The size of a small integer varies depending on command line parameters :} )

Integer d = -129;
Integer e = -129;
System.out.println("(Integer) -129 == (Integer) -129 is " + (d == e));

int x = -129;
int y = -129;
System.out.println("-129 == -129 is " + (x == y));

prints

(Integer) -129 == (Integer) -129 is false
-129 == -129 is true

As for strings, a string literal cache is used. Also the compiler will simplify constant expressions so strings written a different way can be the same.

final int one = 1;
int oneB = 1;
String a = "1";
String b = "" + 1;
String c = "" + one;
String d = "" + oneB;

System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == d);

prints

true
true
false

The contents of each strings is the same, but oneB is not a constant, so the expression is evaluated at runtime and a different string is produced.

IMHO: Java attempts to hide details from developers and it would have been a better choice to make == call equals whereas you could have an operator === if you really wanted to compare actual references .

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.