45

String parts is String[6]:

["231", "CA-California", "Sacramento-155328", "aleee", "Customer Service Clerk", "Alegra Keith.doc.txt"]

But when I compare parts[0] with "231":

"231" == parts[0]

the above result is false,

I'm confused, so could anybody tell me why?

poolie
  • 9,289
  • 1
  • 47
  • 74
omg
  • 136,412
  • 142
  • 288
  • 348
  • 5
    @PaulJWilliams - it does yield an answer: this question. :) – Corin Sep 17 '13 at 17:13
  • I am wondering why the string in the array is not interned, if the array is created using a string literal then the reference comparison should not succeed ? – Sergio Dec 28 '13 at 23:12
  • 1
    What Corin said: Avoid the "just try googling it" snark, because in the future, your snark may in fact be the top google hit. As this is now. (And needing to know the answer to this doesn't mean your a n00b... I switch between so many programming languages these days, I can't remember which ones allow me to do == on strings and which don't. And of those that don't, the only language where I still remember the proper syntax off the top of my head is C. Is there a strcmp in Java? heh...) – user435779 Jan 20 '14 at 20:41
  • Check if you initialize String array with new keyword or not.If you initialize String array with new keyword it doesn't work because new always create new reference.So use this way,String[] array={"231", "CA-California", "Sacramento-155328", "aleee", "Customer Service Clerk", "Alegra Keith.doc.txt"};String str="234";if(str == array[0]){System.out.println("Works");} – Navin a.s Aug 02 '17 at 18:30

12 Answers12

78

The == operator compares the object references, not the value of the Strings.

To compare the values of Strings, use the String.equals method:

"231".equals(parts[0]);

This is true with any other object in Java -- when comparing values, always use the equals method rather than using the == operator.

The equals method is part of Object, and should be overridden by classes which will be compared in one way or another.

coobird
  • 159,216
  • 35
  • 211
  • 226
15

If the strings are not interned, then == checks reference identity. Use:

 "231".equals(parts[0]);

instead.

Yishai
  • 90,445
  • 31
  • 189
  • 263
  • 2
    +1 for mentioning that string literals return true when compared to each other. A student of mine would not believe me that == does not check the actual contents of the string as every example that he gave me used string literals and returned true. – Brandon Bodnar Jun 15 '09 at 12:58
  • @Yishai why the string in the array is not interned, if the array is created using a string literal ? – Sergio Dec 28 '13 at 23:08
  • @Sergio, I imagine the question is contrived in that way, and is just listing the contents of the array, not how they were created. – Yishai Dec 29 '13 at 00:45
  • What I want to say is that if a String is created with: `string=new String[]{"231"}[0];` it is NOT interned, and I do not know why since the string is hardcoded in the code (the array is using a string literal). – Sergio Dec 29 '13 at 08:58
  • @Sergio, if you are basing that on the question, I don't think that was actually happening that way, just the OP simplified it that way. If you have experienced this, then I don't know, – Yishai Dec 29 '13 at 15:26
  • The surprising thing is that if the string is created as I said above it is not interned. I think I will ask why in a separate question. – Sergio Dec 29 '13 at 20:11
13

== in Java compares the address of the objects (strings in this case).

What you want is parts[0].equals("231")

David Johnstone
  • 24,300
  • 14
  • 68
  • 71
  • 4
    It compares the object identity. That *might* be implemented internally as the address, but the JVM spec and the JLS don't talk about addresses here. – Joachim Sauer Sep 15 '11 at 11:51
  • Yeah, I saw that too. It's a nitpick, but technically speaking you can't say it compares the address. (Even though I'd be kinda shocked if there exists any JVM that *doesn't* implement it that way...) – user435779 Jan 20 '14 at 20:43
13

The following prints out "true";

String s = "231";
if(s == "231")
{
    System.out.println("true");
}
else
{
    System.out.println("false");
}

This is because Strings are not mutable and java will try and save as much space as possible, so it points both to the same memory reference.

However, the following prints out "false":

String s = new String("231");
if(s == "231")
{
    System.out.println("true");
}
else
{
    System.out.println("false");
}

new will force it to store the string in a new memory location.

By the way, you should ALWAYS use .equals() to compare strings (for cases just like this one)

Cache Staheli
  • 3,510
  • 7
  • 32
  • 51
Jesse
  • 1,485
  • 1
  • 12
  • 21
7

Use equals method: parts[0].equals("231"). == operator compares object references.

tputkonen
  • 5,579
  • 16
  • 60
  • 88
5

"==" compares object references, in your case "231" is a different object than parts[0].

You want to use String.equals.

parts[0].equals("231")
basszero
  • 29,624
  • 9
  • 57
  • 79
  • 5
    It's often a good idea to use "foo".equals(bar) instead of bar.equals("foo"). The first piece of code will work regardless of whether or not bar is null. The second piece of code will throw a NullPointerException. – William Brendel Jun 15 '09 at 18:06
4

The answer is very simple: when you compare strings through == operator, you actually compare if two different variables refer to a single String object. And they don't, the string in the array and newly created "231" are different String objects with the same contents.

The right thing to do is to use the folllowing expression: "231".equals(parts[0]) or "231".equalsIgnoreCase(parts[0]). This will give you what you need and return true if these String objects contain the same values.

Malcolm
  • 41,014
  • 11
  • 68
  • 91
2

You may also use compareTo(String) method:

String str = "test";

if( str.compareTo("test") == 0)
   //the argument string is equal to str;
else
   //the argument string is not equal to str;
JCasso
  • 5,423
  • 2
  • 28
  • 42
  • 1
    It's only a bit more expensive than `equals()` and not really to be used to compare strings on **equality**. – BalusC Jan 09 '10 at 21:49
  • Talking about performance, we have to mention hashCode and intern... Also there are some exceptions that compareTo runs faster. If two strings has the same reference or they have different length equals give better performance however reference check and length check is redundant sometimes such as comparing substrings for equality. compereTo method gives a better performance if two strings does not have same reference (user input, substring) and having same length. – JCasso Jan 09 '10 at 22:12
2

I thought it might be helpful to express the answer in a test case:

public class String231Test extends TestCase {
    private String  a;
    private String  b;

    protected void setUp() throws Exception {
        a = "231";
        StringBuffer sb = new StringBuffer();
        sb.append("231");
        b = sb.toString();
    }

    public void testEquals() throws Exception {
        assertTrue(a.equals(b));
    }

    public void testIdentity() throws Exception {
        assertFalse(a == b);
    }
}
Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
1

Here's really nice example. The '==' operator with string can be really tricky in Java.

class Foo {
    public static void main(String[] args) {
        String a = "hello";
        String b = "hello";
        String c = "h";
        c = c + "ello";

        String operator = null;

        if(a == b) {
            operator = " == ";
        } else {
            operator = " != ";
        }

        System.out.println(a + operator + b);

        if(a == c) {
            operator = " == ";
        } else {
            operator = " != ";
        }

        System.out.println(a + operator + c);

        if(a == "hello") {
            operator = " == ";
        } else {
            operator = " != ";
        }

        System.out.println(a + operator + "hello");

        if(c == "hello") {
            operator = " == ";
        } else {
            operator = " != ";
        }

        System.out.println(c + operator + "hello");
    }
}

Which will produce following output:

hello == hello
hello != hello
hello == hello
hello != hello
picca
  • 857
  • 1
  • 10
  • 16
  • 1
    Actually everywhere you use literal "hello" directly, it points to the same object created during compile time, so called interned string, hence reference equality test by == passes, but `c` is composed in run-time and points to other object, so it is not reference-wise equal to any "hello" literal. – kstep Jun 30 '13 at 21:33
1

Use the equals method to compare objects:

String[] test = {"231", "CA-California", "Sacramento-155328", "aleee",
                 "Customer Service Clerk", "Alegra Keith.doc.txt"};

System.out.println("231".equals(test[0]));

The comparison '==' compares references, not values.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Don Branson
  • 13,631
  • 10
  • 59
  • 101
0

As many others have already explained, you try to compare with equality operator, but then it would relies on Object.equals() instead of String.equals().

So you can do the job by explicitly calling String.equals(), but instead of writing

parts[0].equals("blahblah")

I would prefer such :

"blahblah".equals(parts[0])

As it avoids testing potential nullity of parts[0] (but be careful that parts variable itself could be null...)

Another way is using String.intern() :

if (parts[0].intern() == "blahblah") ...

See http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#intern() for more info on that.

Michael Zilbermann
  • 1,398
  • 9
  • 19
  • Interning the string just so you can use == on it is not good advice, since it uses time and memory. Also, that link is now broken. – poolie Nov 25 '13 at 20:05