-7
String s = "Hi Hello Hola";
String[] d = s.split(" ");
System.out.println(d[0] == "Hi"); // prints false
String[] e = { "Hi", "Hello", "Hola" };
System.out.println(e[0] == "Hi"); // prints true

Here we have an array d with the values Hi, Hello, and Hola. We have another array e with the same set of values.

But why does this comparison behaves differently? Why does it print false and then true?

I expected false for both! As we are comparing a string literal value with the string value by using ==.

Why is this difference?

Update Here my question is not about the comparison of String values. I'm aware of the differences between == which compares the references and equals() which compares the content of the string.

From the answers, i understand that in the second case, Hi value is interned and refers to the same object. But in the other case, split creates new values without checking the literal pool. Is it right? Am i missing anything?

RamValli
  • 4,389
  • 2
  • 33
  • 45
  • 2
    A quick search on the site, before asking, would have been a good idea, there are tons of similar questions.. –  Dec 16 '15 at 07:09

3 Answers3

1

The reason beeing is the compiler. At compile time the compiler does notice that the literal Hi exists twice in the code and does intern this string for your specific class. After compilation both of your interned strings Hi are pointing to the same reference of Hi. That´s the reason why the second print results in true.

The split doesn´t know it´s result and creates new references for the corresponding Strings. That´s the reson why Hi from the split and the literal Hi are not using the same reference.

SomeJavaGuy
  • 7,307
  • 2
  • 21
  • 33
1

This is happening because internally when split(Pattern) matches the pattern, and finds the matching char sequences, then it uses String.substring(start,end) for creating a new String object. That is why results returned by split are false. This is code snippet from java.util.regex.Pattern.split(CharSequence input, int limit) class.

String match = input.subSequence(index, m.start()).toString();

Here the input is instance of the String class, which is passed to the Pattern.split(CharSequence, int) method.

Reference: Pattern

YoungHobbit
  • 13,254
  • 9
  • 50
  • 73
0

Trying to use '==' on strings is very unpredictable. The first time you type in "Hi" as a literal, it is saved into memory. When you then assign it into the array 'e', it uses that same saved literal for storing it in the array. When you then check to see if they are equal, it resolves as true.

I highly recommend not using '==' and use one of the many methods that are provided in Java.

System.out.println("Hi".equals(d[0]));
System.out.println("Hi".equals(e[0]));

or...

System.out.println(("Hi".compareTo(d[0]) == 0));
System.out.println(("Hi".compareTo(e[0]) == 0));
Cody Moorhouse
  • 227
  • 2
  • 5