String array vs String split array [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
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?

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.

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

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));

Related

How is this thing works internally? [duplicate]

This question already has answers here:
Comparing strings with == which are declared final in Java
(6 answers)
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
Please follow the code below:
String s="helloworld";
String ss="hello";
String sss=ss+"world";
System.out.print(sss==s);
The output is false. Don't they get checked with the string pool rule for String? And what if we make them final?
A little explanation of internal working will help. Thanks in Advance.
String literals points to the same location if the content of them is same, that's what I got from different sources, am I right? If yes, then what's happening here? I'm a little confused about it.
EDIT:-
I think I didn't phrase it correctly. Let me rephrase it a little(Sorry for earlier attempt):-
String ss="hello";
System.out.print(ss+"world"=="helloworld");
This returns false. However these are String literals and as I have read they don't create two different objects for same value. They are just reference to a same value. Here, "helloworld" is the value for both sides of ==. I hope that I'm able to communicate it well.
Because String is an object, it is comparing that the two objects are the same with ==, which will equate to false.
Using the object ss to concat into sss will not make s = sss.
If you set ss to s, then using == will equate to true since they are now the same object.
If you set a second String object with a string literal, using == will equate the true.
If you use the String object's function .equals(String), you will find that it equates to true.
If you compare two string literals, i.e. "helloworld" == "helloworld" or "helloworld" == "hello" + "world", these will also equate to true.
As lealceldeiro pointed out, strings should always be compared with .equals().
EDIT
A good thing to look at is this answer. It has good references and explanation.
Other resources:
JournalDev
Baeldung

Java test String Handling [duplicate]

This question already has answers here:
Comparing strings with == which are declared final in Java
(6 answers)
Closed 7 years ago.
I was doing some java tests to practice and I came across a question that I don't understand. I created a small program to test it:
The question was to say what would be the output of System.out.println(ab==abc);
I answered 'true' thinking that String literals are not objects, so the can be seen as a kind of primitive type so the comparation == would compare the values and nothing to do with references. But actually the answer in "false";
Then I did this test and I even print the outputs and as you can see ab and abc are exactly the same, however the comparation is returning false , but if I do the comparation directly without doing any concatenation (as I did at the end of the program) the comparation is returning true. So it seems clear the reason has to be with the concatenation, I know that Strings are inmutable so when concatenating then we are getting another String literal with exactly same value.
Can someone please explain me who't going on here?
For those telling me that String literals are objects, why then this code returns true?
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output true
Of course I would understand that this code
String o=new String("meowdeal");
String p=new String("meowdeal");
System.out.println(o==p);
returns false because in that case they are really objects but not when they are String literal, am I right?
Thank you for your time
public static void main(String ads[] ){
String a="meow";
String ab=a+"deal";
String abc="meowdeal";
System.out.println(a);
System.out.println(ab);
System.out.println(abc);
System.out.println(ab == abc);
//output
//meow
//meowdeal
//meowdeal
//false
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output
//true
}
ab and abc are objects so .equals() is used to see if they have the same contents and == is used to see if they are the same object.
The last test is only true due to a compile optimization known as string interning
(Your second comment below is correct)
In Java you should compare Strings with .equals(String s) because the '==' returns only true if it's the exact same String in the memory and doesn't compare if the content is the same. In your first example you've got two different strings in your memory. In the second, java saw, that these would be the same and allocated only space for one string and your p and o are only a reference to the same object.
String literals are Objects. User equals method instead of == operator.
Just to explain what happen here,
String p="meowdeal"; //creates "meowdeal" in heap
String o="meowdeal"; // o also refer to same object in heap.
This is called pooling of String. Since both refer to same memory location == operator returns true.

Can anyone please explain why output of the following is such? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
String str1 = "abc:5";
String str2 = "abc:" + str1.length();
String str3 = "abc:" + 5;
System.out.println(str1==str2);
System.out.println(str1==str3);
Output of the program is :
false
true
But I don't understand why?
== operator will compare reference only
.equals() will compare the values.
in your case
str1==str2 // compares the two references, which are different.
had it been, str1.equals(str2), it would have compared the values, which will return true
The “==” operator
In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.The “==” operator compares the objects’ location(s) in memory
The “equals” method
The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory.
Here str1 = "abc:5"; is located in constant pool of string and str2 is concatenated with 2 different object with new operator. So both str1 and str2 are referring to different object. That's the reason it is showing false.
The == operator is used for only reference variables in java. For example if you are comparing characters a1 and a2 you can use the == operator because the char type is highlighted in most IDEs in Java. To check if two Strings are equal to each other you can use .equals()or .equalsIgnoreCase() to compare the Strings. This is because Strings are objects, not primitives, and require their own method in the class to test if Strings are the same.
For the first System.out.println(); statement, you would use System.out.println(str1.equals(str2)); or System.out.println(str1.equalsIgnoreCase(str2));.
For the second System.out.println(); statement, you would use System.out.println(str1.equals(str3)); or System.out.println(str1.equalsIgnoreCase(str3));.

What does == in java represent? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
What is "==" in Java ? Why can i only compare numerical data type with it and characters can be compared. But not the string data types. What does it provide when i compare two strings?
== compares reference equality: it returns true if its operands have the same value on the stack. (that is, they are either the same numerical quantity or they point to the same object)
Strings are objects, so here we're asking whether they point to the same object on the stack. This will be true if we're talking about String literals defined in code:
If we have
String s1 = "Hello";
String s2 = "Hello";
then s1 == s2 => true
However, if one of the Strings is obtained by some run-time process, for example user input, then it will not be reference-identical, even if the contents of the two Strings are the same.
In Java == compare reference two reference value. If left side reference equals to right side reference will return true else false.
When you come to compare String(objects) you should use equals()
Why?
String a= new String("a");
String b= new String("a");
Here a and b are same by value but they have two different reference.
If you compare to objects (strings are objects) you will compare the reference of both objects.
The '==' operator in Java is used to compare similar variables (like an integer and another integer). For an over-complicated reason, Strings are considered 'Object' type variables. To compare strings use the operator variableString.equals(otherString);

Comparing two strings with equal(==) operator [duplicate]

This question already has answers here:
String comparison and String interning in Java
(3 answers)
Closed 9 years ago.
I was kind of telling some one that , we must use String.equals method to compare two strings values, we can not simply use == operator in java to compare Strings, and told him that == will return false as it doesn't compare the string value but String object reference value.
I have written this example to show him, but for my surprise it always prints true for == operator..
here is the code
public void exampleFunc1(){
String string1 = "ABC";
String string2 = "ABC";
if(string1 == string2)
System.out.println("true");
else{
System.out.println("false");
}
System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
System.out.println(" Are they equal "+(string1.equals(string2)));
}
Output:-
Are they equal true
Are they equal true
So question here is in what circumstances == operator on objects can print true, except that both objects are same instance?
String is one of a few special cases.
Class String keeps a special pool of "interned" Strings. Method myString.intern() looks up myString in this pool. If another String with the same contents already exists in the pool, a pointer to it is returned. If not, myString is added (and a pointer returned).
When you say myString= myString.intern() ;, you are effectively making myString refer to a shared copy or its underlying String available for future sharing (and no duplication). Most library methods creating Strings are subject to this, particularly String literals.
Other cases of "interning" occur with wrapper types Integer, Long, etc. They don't have constructors, but static methods valueOf() that return pre-built, shared objects when they can (usually the 256 values closest to zero), and new objects when they can not. The later is not much problematic because these types are more lightweight than Strings. Long, for example, has a payload of just 8 bytes. String contains a char[] that even empty is 16 bytes or so.
To answer your question, you can not count on any "interning" mechanisms. They have changed in the past, and they could change in the future (or even from one JVM to another), making your code unusable. Always use equals.
You should use
String string1 = new String("ABC");
String string2 = new String("ABC");
Then everything would be correct like what you think,
In this case, "ABC" is just a reference to a const string.
The compiler may be optimizing the assignments and only creating one String object. If you use the explicit String constructor, the == operation should behave as expected.

Categories