I observed a strange behavior == operator in java. I am trying to print the out put as follows
String str1 = "Rajesh";
String str2 = "Rajesh";
System.out.println("Using equals() str1 and str2 Equals :"
+ str1.equals(str2));
System.out.println("Using == str1 and str2 Equals :"
+ str1 == str2);
The first SOP statement printing
Using equals() str1 and str2 Equals :true
and the next SOP printing only false .
I tried compiling in both eclipse and Net Beans but result is the same .
I am so confused why
Using == str1 and str2 Equals :
is not printing
Help me out in this
Thanks in advance,
Raj
it's the same as ("Using == str1 and str2 Equals :" + str1) == str2 and this is false, of course. Expression is parsed from left to right and so at first it concatenates "Using == str1 and str2 Equals :" and str1, then applies == operator.
See http://bmanolov.free.fr/javaoperators.php for a table of operator precedence in Java.
The + operator is higher precedence than the == operator.
So, in effect, your code is equivalent to the following:
System.out.println( ("Using == str1 and str2 Equals :" + str1) == str2);
Note the placement of the parentheses that I added. It evaluates to this:
System.out.println( (str_x + str1) == str2);
And then to this:
System.out.println( str_y == str2 );
And then to this:
System.out.println( false );
In order to get the result you want, you must use parentheses to specify that you want the == operator to be resolved BEFORE the + operator:
System.out.println( "Using == str1 and str2 Equals :" + (str1 == str2));
Notice the new placement of the parentheses.
Because + has higher priority compare to = and if you use bracket(str1 == str2) then
this result give true because highest priority is (.
So First it checks bracket inside data.
String str1 = "Rajesh";
String str2 = "Rajesh";
System.out.println("Using equals() str1 and str2 Equals :"
+ str1.equals(str2));
System.out.println("Using == str1 and str2 Equals :"
+ (str1 == str2));
Output:
Using equals() str1 and str2 Equals :true
Using == str1 and str2 Equals :true
Maybe an order of operations thing? Try:
System.out.println("Using == str1 and str2 Equals :" + (str1 == str2));
Try surrounding it with () like this:
System.out.println("Using == str1 and str2 Equals :" + (str1 == str2));
equals method returns true if and only if x and y refer to the same object.Follwoing is the Object class implementation of equals method.
public boolean equals(Object obj) {
return (this == obj);
}
In String class this method has overridden as following.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
And if you use == operator it just check both references are having same object. Similar to the Object class equals method.
The reason is that you cannot compare strings in Java using ==.
In C++ or C# (or other languages supporting operator redefinition), you can overwrite the == operator to provide that functionality. Java does not support that.
str1.equals(str2) returns true because the equals() function compares the content of the string variables, where as == operator compares the instances. Since str1 and str2 are two differences of instances of String class, it returns false
In Java == operator matches the two objects i.e their address while .equals() method mathces the values of both objects, thats why you are getting true for equals() and false for == as both are different objects.
== can only be used to compare primitive datatypes. To compare objects you need to use equals method. Using a == operator on objects actually compares there addresses instead of values.
Related
I've been using JShell a bit just to test it out, and today I came across quite the interesting bit of behavior.
jshell> String a = "A"
a ==> "A"
jshell> String b = "A"
b ==> "A"
jshell> a == b
$4 ==> true
jshell> "A" == "A"
$5 ==> true
I was first wondering if this was a feature of Java 9, and I checked it out by compiling and running this program with Java 9
public class Equus {
public static void main(String... args) {
String a = "A";
String b = "A";
System.out.println("a == b");
System.out.println(a == b);
System.out.println("\"A\" == \"A\"");
System.out.println("A" == "A");
}
}
And interestingly enough I got
a == b
true
"A" == "A"
true
As my output as well. What's going on here? Why are a and b equal to each other and why is "A" == "A" true?
Why shouldn't it be? This behaviour is exhibited in previous Java versions as well - String literals are interned.
As you know, == checks for reference equality - the two variables have the same memory address. When a String is interned, all references of that string point to the intern pool and thus will be equal using ==.
I just wanted to add this demonstration alongside Sinkingpoint's fine answer.
It's not safe to use == on Strings unless you know the origin of each, since a String that is built-up in some way (such as the new String("A") in Eli's comment or the .toString() used here) is not the same reference even if the two do use the same underlying character array.
class Main
{
public static void main(String[] args)
{
String oneA = "A";
String twoA = "A";
String three = new StringBuilder().append('A').toString();
// We expect constant literals to be ==
System.out.print("A == A -> ");
System.out.println("A" == "A");
// Variables assigned the same literal are also ==
System.out.print("oneA == twoA -> ");
System.out.println(oneA == twoA);
// but a built-up String var is not == to the "literal" var.
System.out.print("oneA == three -> ");
System.out.println(oneA == three);
// If we intern() them they are again ==
System.out.print("oneA.intern() == three.intern() -> ");
System.out.println(oneA.intern() == three.intern());
// and of course, .equals() is always safe.
System.out.print("oneA .equals three -> ");
System.out.println(oneA.equals(three));
}
}
The output from this (run on https://repl.it/languages/java) is:
A == A -> true
oneA == twoA -> true
oneA == three -> false
oneA.intern() == three.intern() -> true
oneA .equals three -> true
You can safely use string1.equals(string2) or string1.intern() == string2.intern()
This question already has answers here:
Why are the results of of str == str.intern() for these strings different?
(4 answers)
Closed 3 years ago.
I have the code like this:
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1); //true
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2); //false
String str3 = new StringBuilder("Str").append("ing").toString();
System.out.println(str3.intern() == str3); //true
I can understand why str1.intern() == str1 and str3.intern() == str3 are true, but I don't understand str2.intern() == str2.
Why this is false?
My java version is: 1.8.0_73
String.intern() returns a String in the string literal pool. However if the string already exists in the pool, it will return the existing String.
If you pick a new String, it should return the String you created, but if you use a String which happens to exist in the pool already you will get the existing String.
It is reasonable to assume that in this case "java" already exists in the pool so when you call intern() it returns a different object so == is false.
note: string.intern().equals(string) should always be true.
The constant String "java" already exists in the Java constant pool, but you can verify that by changing
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
to
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == "java");
which will get the same constant and output
true
Alternatively, you could add "计算机软件" and "String" to the constant pool like
String a = "计算机软件";
String b = "String";
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str3 = new StringBuilder("Str").append("ing").toString();
System.out.println(str3.intern() == str3);
Then you would get (consistent with your observations)
false
false
This question already has answers here:
String equals and == with String concatenation [duplicate]
(4 answers)
Closed 7 years ago.
String a = "abc";
String b = "abc";
System.out.println("Result .... " + a==b); // false
System.out.println(a==b); // true
1st print statement prints false and 2nd prints true, though ideally it has to be true. Why is it false in 1st print statement ?
System.out.println("Result .... " +a==b); -> the result string will be appended with 'a' and then compares with b so it results false.
Order of operations:
"Result .... " + a==b
is equivalent to
("Result .... " +a) == b
which will be false since the two strings are not the same reference.
The explanation for this is that the + addition operator has a higher precedence than == logical equivalence.
The expression a == b is returning true in your second statement due to interning, in which a and b actually refer to same string object.
Click here for a link to Oracle's table of operator precedence in Java.
Forgot checking equality by == in java. In Java this operation checks equality of object link. Additionally it is applicable for checking equality of simple numbers. You should use .equals method
String a = "abc";
String b = new String(a);
System.out.printLn(a == b);//false
System.out.println(a.equals(b));//true
Learn about operation order in java
It is because in "Result .... " +a==b it first add "Result .... " with a and then == to b. If you write like this "Result .... " +(a==b), then it will be OK.
In the first statement, you're comparing "Result .... " + a with b. In the second one, you're comparing a with b, hence the difference. Change your first statement as follows:
System.out.println("Result .... " + (a==b));
And keep in mind that strings should be compared using the equals() method instead of ==.
System.out.println("Result .... " +a==b);
String Result is appended with 'a' and then compares with b so it provides false. (Result .... a == b) which is false.
Follow this link to understand precedence of operators in java and this.
Operator + has more precedence than == operator.
try adding brackets, you will see the diff. Bracket is evaluated separately.
public static void main(String[] args) {
String a = "abc";
String b = "abc";
System.out.println("Result .... " + (a == b)); // false
System.out.println(a == b); // true}
}
output
Result .... true
true
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I have this code which I cannot understand. In the beginning you can see two identical Strings, and when I compare them with use of operator == it says it is true, same as equals() method, but when I create two identical strings during runtime operator == says false. Why is this happening ?
Does it mean that when I hardcode identical strings they are placed in the same position in the memory and both references point to it? I found similar question, but there were no explicit answer.
public class StringTesting {
public static void main(String[] args){
String string1 = "hello"; //\
// } same place in the memory ?
String string2 = "hello"; ///
System.out.println(string1 == string2); //true
System.out.println(string1.equals(string2)); //true
String string3 = "hey";
String string4 = "he";
System.out.println(string3 == string4); //false
System.out.println(string3.equals(string4)); //false
string4 += "y";
System.out.println(string3 == string4); //false ????
System.out.println(string3.equals(string4)); //true
System.out.println(string3 + " " + string4); //hey hey
}
}
The following compound assignment operator:
string4 += "y";
performs String concatenation at runtime. Since the value of string4 is evaluated at runtime only. And String concatenation done at runtime creates a new object.
From JLS Section 3.10.5 (See towards the end of this section):
Strings computed by concatenation at run time are newly created and therefore distinct.
However if you perform concatenation of two string literals, it won't create a different objects. So the following code will return true:
"he" + "y" == "hey";
That JLS section contains code segment for various string concatenation example:
String hello = "Hello",
String lo = "lo";
System.out.print((hello == "Hello") + " "); // true
System.out.print((Other.hello == hello) + " "); // true
System.out.print((other.Other.hello == hello) + " ");// true
System.out.print((hello == ("Hel" + "lo")) + " "); // true
System.out.print((hello == ("Hel" + lo)) + " "); // false
System.out.println(hello == ("Hel" + lo).intern()); // true
string4 += "y"; creates a new object.
String literals however are placed in the same place in memory as an optimization (this is called string interning).
string1, string2, and string3 are all string constants. i.e., they appear as constant pool entries in the .class file. In Java, string constants are interned.
string4 is a new string, created by taking the string constant "he" and then appending "y". Therefore, it's not a string constant, and is not interned.
That is why string3 != string4.
I'm trying to write a method that checks if a string has only numbers in it. For some reason it returns false even if I input a string containing "1234". I'm guessing my problem is with the if statement, but I'm not sure what to do to fix it.
public static boolean isNumeric(String input)
{
input.trim();
for (int count=0; count<=input.length(); count++)
{
if (input.substring(count) == "0" || input.substring(count) == "1"||
input.substring(count) == "2" || input.substring(count) == "3" ||
input.substring(count) == "4" || input.substring(count) == "5" ||
input.substring(count) == "6" || input.substring(count) == "7" ||
input.substring(count) == "8" || input.substring(count) == "9")
{
integerstate = true;
}
else
{
integerstate = false;
break;
}
}
return integerstate;
}
Does anyone see what the problem is?
#Kal's answer is literally correct, but my goodness, #Petefic, this is a horribly inefficient way to do things. There's a method in the Character class that checks if a char is a digit, and you could just extract each character once instead of calling substring() so many times.
For instance, you might do
public static boolean isNumeric(String input) {
input = input.trim();
for (char c: input.toCharArray()) {
if (Character.isDigit(c))
return true;
}
return false;
}
For the number 99999, your code would produce over 50 new objects; this would produce one (the array from toCharArray().)
I see a few other answers that suggest using Integer.parseInt() and catching the exception. That's not a terrible idea, but it's actually not a great one if many of the strings will not be numbers. Throwing and catching an exception is very computationally expensive; many objects are created in the process. It should be avoided in cases where actual error recovery is not involved.
Use "0".equals(input.substring(count) ) instead of ==
== is checking for object equality and not string equality
See this question for how to do it the way #Ernest suggests.
public static boolean isNumeric(String input) {
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(input);
if (isNum.matches()) {
return true;
}
return false;
}
Another option would be to use charAt() instead of substring and compare against '0', '1' etc. Then you can use ==. A far more efficient way however would be to use regular expressions.
Like Kal said, the == operator is determining whether the objects are the same object, not if they have the same value. With Java, this will often get you the same result, which can make it more difficult to realize why using == to compare strings is wrong. It will sometimes work because Java interns Strings with a String pool, which means Java will generally only store one String of each value. In other words, if String x and String y both have the value of "asdf", the String pool will only store "asdf" once and both x and y will reference that String object. The only way to force Java to actually create a duplicate String object is with the "new" keyword. I think in this case, == is not working due to the substring. In any case, unless you're actually checking to see if the objects being referenced are the same, always use .equals().
You might let the tool-kit do the 'heavy lifting'.
class TestForIntegers {
public static void main(String[] args) {
String s = "blah";
System.out.println(s + " is integer: " + isInteger(s));
s = "1234";
System.out.println(s + " is integer: " + isInteger(s));
s = "max123";
System.out.println(s + " is integer: " + isInteger(s));
}
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
return true;
} catch (Exception e) {
return false;
}
}
}
Output
blah is integer: false
1234 is integer: true
max123 is integer: false
Press any key to continue . . .
You should use the equals method for String equality.
And if you want to use it the other way around,consider converting your substrings using Integer.parseInt() and then you can use == 0.
In java to check for equality of two strings or comparing them you need to use the equals() since equals() does the content comparison. But '==' does the reference comparison so it just checks if the two references on both side of '==' are pointing to same object or not.
// Bad
for (int count=0; count<=input.length(); count++)
{
if (input.substring(count) == "0" || input.substring(count) == "1"||
input.substring(count) == "2" || input.substring(count) == "3" ||
input.substring(count) == "4" || input.substring(count) == "5" ||
input.substring(count) == "6" || input.substring(count) == "7" ||
input.substring(count) == "8" || input.substring(count) == "9")
{
integerstate = true;
...
// Better
for (int count=0; count<=input.length(); count++)
{
if (input.substring(count).equals("0") || ...
...
// Much better
try {
Integer.parseInt( input );
integerstate = true;
}
catch ...
The cause behind this is difference between == and equals().
This happen because == compare for exact equality means two object must be same. while equal() compare for meaningful equality means object may not me same but the value they contain are meaningfully same.