1

Consider:

String string1 = "Hi there";
String string2 = "Hi";
String string3 = "Hi";

System.out.println(string1.substring(0, string2.length()) == string2); //1
System.out.println(string1.substring(0, string2.length()).equals(string2)); //2
System.out.println(string1.substring(0, string2.length()).compareTo(string2)); //3
System.out.println(string2 == string3); //4
System.out.println(string2.substring(0) == string3); //5
System.out.println(string2.substring(0) == string3.substring(0)); //6

It gives me the output:

false
true
0
true
true
true

I don't really understand the first line. Why does it give me false?

If I add a whitespace to string 2 and this line I get false, but if I add no whitespace I get true:

System.out.println(string2.substring(0, string3.length()) == string3);

Why should line 1 give me false, but line 6 be true, but if I add a whitespace to string2 it's false?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    How is this insuffucient? http://stackoverflow.com/search?q=Comparing+strings+in+java Didn't you see a list with all links below the subject while you entered down the question message? Did you bother to follow the suggested links? Why not? – BalusC Dec 02 '09 at 15:19
  • Does this answer your question? [How do I compare strings in Java?](https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Donald Duck Jun 09 '23 at 09:18

7 Answers7

14

Several things are going on there.

When you declare two strings to be equal "Hi", Java optimizes it to refer to the same string object (so it doesn't have to store the same string twice).

"==" compares references. When in line 1 you use substring, the created string object has a different reference than string2.

In line 6, I imagine substring(0) has an optimization where it knows it can just return the original string, thus those references are equal.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jean Barmash
  • 4,788
  • 1
  • 32
  • 40
  • Have these optimizations ALWAYS been in Java? I seem to recall an exercise back in Java 2 that might not have returned different results, but my memory's a bit foggy on that. – FrustratedWithFormsDesigner Dec 02 '09 at 15:26
  • 2
    Maybe, maybe not. Either way this is a perfect example for that you should *never* rely on such an optimization. If you need to compare `String`’s, *always* use `equals()`, *never* use `==`! – Bombe Dec 02 '09 at 17:12
  • 1
    In some situations interning the strings and using == will be more performant. – blackanchorage Dec 02 '09 at 19:41
7

If you want to compare Strings, then you should use String.equals() (or String.equalsIgnoreCase()) method. Comparing by == tells you only if two references points to same object. And in your example that's it: string2 and string3 points to same instance of string "Hi" (why should Java create two exactly same strings given in compile-time)

MBO
  • 30,379
  • 5
  • 50
  • 52
  • 1
    +1. It's also worth noting that in general there are very few guarantees about what instance of an object you'll get back from a method - methods can generally do much nicer things if they're free to use instance caching, use dynamic proxies etc. So it's important not to get hung up on object equality and use `equals()` in the general case, comparing references only if you're really sure you need it. – Andrzej Doyle Dec 02 '09 at 15:24
4

The == operator is checking if the two objects are equal (are they references to the same object?), not comparing the values contained therein.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
1

The == compares the references. The address of the string, not the value of it.

For comparing strings, you should use equals. The JVM will handle new String objects, so if an object of the same value exists (string2 vs string3) it might reference the same one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tamar
  • 2,016
  • 1
  • 15
  • 26
1

The == operator is comparing 2 references to the same string for equality.

The String class has two methods that you should use to compare two strings for equality:

String1.equals(String2);

Returns true if String1 and String2 are identical (including the case of the letters).

If you don't care about the case then you can use:

String1.equalsIgnoreCase(String2);

This returns true if String1 and String2 are equal regardless of the case (obviously).

Davie
  • 818
  • 3
  • 12
  • 24
1

Java provides two basic mechanisms for testing for equality. The “==” operator can be used to test primitive values for equality, and can also be used to determine if two object references point to the same underlying object. For Java objects, the equals(Object) method will return true if the argument is equal to the object on which the method is invoked, where equality is defined by the object’s class semantics.

Since Strings are objects, the equals(Object) method will return true if two Strings have the same contents, i.e., the same characters in the same order. The == operator will only be true if two String references point to the same underlying String object. Hence two Strings representing the same content will be equal when tested by the equals(Object) method, but will only by equal when tested with the == operator if they are actually the same object.

Quoted from JavaTechniques:http://javatechniques.com/public/java/docs/basics/string-equality.html

JuanZe
  • 8,007
  • 44
  • 58
  • Related: *[What do we do with answers that are entirely copied and improperly attributed (only a "reference" link or similar is included)?](https://meta.stackoverflow.com/questions/321299/)* – Peter Mortensen Aug 07 '23 at 17:37
0

Lines 4, 5, and 6 are true because of the following lines in the method substring(int, int) of java.lang.String:

return ((beginIndex == 0) && (endIndex == count)) ? this :
    new String(offset + beginIndex, endIndex - beginIndex, value);

Because the substring you are requesting starts at 0 and has the length of the complete string you are simply returned a reference to the string itself so that a.substring(0) == a.

Bombe
  • 81,643
  • 20
  • 123
  • 127