Categories
java string

String.equals versus == [duplicate]

569

This code separates a string into tokens and stores them in an array of strings, and then compares a variable with the first home … why isn’t it working?

public static void main(String...aArguments) throws IOException {

    String usuario = "Jorman";
    String password = "14988611";

    String strDatos = "Jorman 14988611";
    StringTokenizer tokens = new StringTokenizer(strDatos, " ");
    int nDatos = tokens.countTokens();
    String[] datos = new String[nDatos];
    int i = 0;

    while (tokens.hasMoreTokens()) {
        String str = tokens.nextToken();
        datos[i] = str;
        i++;
    }

    //System.out.println (usuario);

    if ((datos[0] == usuario)) {
        System.out.println("WORKING");
    }
}

5

  • 2

    Have a look at this thejavageek.com/2013/07/27/…

    Sep 26, 2013 at 12:38

  • 3

    “==” compares reference and not the content.Change datos[0] == usuario to datos[0].equals(usuario) to get the correct answer

    Jan 27, 2014 at 8:28

  • 2

    I see you changed your accepted answer – I urge you to read my comments on that and reconsider. The “story” in the now accepted answer might look good initially, but IMHO it really doesn’t bear scrutiny.

    – Alnitak

    Jul 18, 2014 at 19:46

  • This article can help you in understanding this.

    Aug 23, 2020 at 5:32

  • Most language work this way, you just don’t see it because most languages have operator overloading and the == operator for strings has been overloaded to call the languages equivalent of string.equals. Java doesn’t have operator overloading, so you have to do it the hard way, like a cave man. Java also doesn’t complain or warn you when comparing strings in this way, so it becomes a runtime error that you get to hunt down. Why doesn’t Java have operator overloading? Because they wanted to keep the language simple, then they realised it was too simple and made working with dates complicated.

    Sep 5, 2020 at 5:03

597

Use the string.equals(Object other) function to compare strings, not the == operator.

The function checks the actual contents of the string, the == operator checks whether the references to the objects are equal. Note that string constants are usually “interned” such that two constants with the same value can actually be compared with ==, but it’s better not to rely on that.

if (usuario.equals(datos[0])) {
    ...
}

NB: the compare is done on ‘usuario’ because that’s guaranteed non-null in your code, although you should still check that you’ve actually got some tokens in the datos array otherwise you’ll get an array-out-of-bounds exception.

11

  • 10

    @mo: It isn’t equally handled, as you can see by this example.

    May 16, 2012 at 14:37

  • 56

    @mo in some cases even in java == can be misleading. Java caches strings and so something like this would return true. String a = "Hello"; String b = "Hello"; a == b is true even though one would normally expect the result to be false.

    Jul 24, 2012 at 14:19

  • 6

    @JonTaylor Your example has nothing to do with caching. Typing “Hello” in java code actually creates an anonymous static String object in the class. If you are using a good compiler, multiple occurrences of “Hello” might use the same static String object, but it would be equally valid to replace “Hello” with new String(new char[] {'H', 'e', ...})

    Sep 19, 2013 at 9:46


  • 10

    @parasietje The JLS guarantees that multiple occurrences of “Hello” (as a literal) refer to the same String object. A compiler can’t replace it with something else.

    – fgb

    Oct 5, 2013 at 14:41


  • 5

    Be very careful using == to compare strings, unless both were initialised with literals == will always return false. For example, this will print false: String a = "abc"; String b = "abcd"; a += "d"; System.out.println(a == b);

    – Galax

    May 19, 2016 at 21:06


579

Meet Jorman

Jorman is a successful businessman and has 2 houses.

enter image description here

But others don’t know that.

Is it the same Jorman?

When you ask neighbours from either Madison or Burke streets, this is the only thing they can say:

enter image description here

Using the residence alone, it’s tough to confirm that it’s the same Jorman. Since they’re 2 different addresses, it’s just natural to assume that those are 2 different persons.

That’s how the operator == behaves. So it will say that datos[0]==usuario is false, because it only compares the addresses.

An Investigator to the Rescue

What if we sent an investigator? We know that it’s the same Jorman, but we need to prove it. Our detective will look closely at all physical aspects. With thorough inquiry, the agent will be able to conclude whether it’s the same person or not. Let’s see it happen in Java terms.

Here’s the source code of String’s equals() method:

enter image description here

It compares the Strings character by character, in order to come to a conclusion that they are indeed equal.

That’s how the String equals method behaves. So datos[0].equals(usuario) will return true, because it performs a logical comparison.

10

  • 23

    I love intuitive examples and this is one of the best I’ve ever seen. Novice programmers can easily understand what’s going behind the scenes reading this.

    May 4, 2014 at 9:18

  • 13

    I actually think this answer is really confusing because it conflates the person’s name with the person themself. It also confuses “equality” with “equivalence”. The this == anObject check is semantically exactly a test that one is comparing the same two objects (equality), which by definition therefore must be equivalent. The final return true after the while loop does not mean we have the same “Jorman”, it means the that the two entities share the same value (equivalent) which does not imply equality. (The Java .equals method is misnamed in this regard).

    – Alnitak

    Jul 18, 2014 at 19:40


  • 1

    This answer is for newbies, the next answer, the one by Michal Bernhard provides the correct analysis of Java’s inconsistent behavior of == when applied to string.

    – Shakti

    Oct 24, 2014 at 4:35


  • 3

    @DavidT. you forgot the check for fingerprints 🙂

    May 20, 2015 at 14:46


  • 2

    -1 since no hand drawn red circles – and seriously, +1 for the Jorman guy.

    – user719662

    Jan 14, 2016 at 20:42

100

It’s good to notice that in some cases use of “==” operator can lead to the expected result, because the way how java handles strings – string literals are interned (see String.intern()) during compilation – so when you write for example "hello world" in two classes and compare those strings with “==” you could get result: true, which is expected according to specification; when you compare same strings (if they have same value) when the first one is string literal (ie. defined through "i am string literal") and second is constructed during runtime ie. with “new” keyword like new String("i am string literal"), the == (equality) operator returns false, because both of them are different instances of the String class.

Only right way is using .equals() -> datos[0].equals(usuario). == says only if two objects are the same instance of object (ie. have same memory address)

Update: 01.04.2013 I updated this post due comments below which are somehow right. Originally I declared that interning (String.intern) is side effect of JVM optimization. Although it certainly save memory resources (which was what i meant by “optimization”) it is mainly feature of language

4

  • 6

    It’s actually not just a side effect of jvm optimization and has nothing to do with the compiler at all. The identity of static strings (literals) across all classes is guaranteed according to the Java VM Specification and works with every VM that is at least Java 1.1 compatible.

    – x4u

    Feb 6, 2010 at 7:20


  • 7

    If you mean JVM spec chapter 2.3 “String literals and, more generally, strings that are the values of constant expressions are “interned” so as to share unique instances, using the method String.intern”. Well it’s guaranteed by jvm (according to spec), but for me this still means optimization. There is no semantic value of this AFAIK. On the other hand == has semantic “identity equality” and method equals() has “object equality” so you should obey this and no rely on jvm specification, which is “guide” for jvm implementators rather then for developers (they have Java Language Specification).

    Jul 14, 2011 at 21:07


  • 3

    The literals, classnames and the likes are interned to comply with the spec, it’s not mere optimization. “xxx” is always == “xxx”, this is part of the language design not an impl. detail/guideline.

    – bestsss

    Jun 7, 2012 at 12:52

  • 1

    Actually, using == always returns the expected result. The problem is in some people having wrong expectations about the result. This is not a problem of the language, rather of their lack of knowledge. If they expect == to always return the same as the result of .equals, they should re-read their textbook. If, on the other hand, they expect == to return a comparison of reference, they’ll notice it’ll always return what they expect.

    – Stultuske

    May 8, 2015 at 7:18