What is going on with equality in JShell/Java 9? - java

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

Related

Checking for empty string using .equals(), .isEmpty() and .length() in Java

I am writing some code to check if two strings are anagrams, in Java. This is for the Anagrams problem on Hackerrank.
My code is failing only 1 of the 17 test cases, and I'm guessing it's due to invalid inputs. This is where my issue lies. At the very beginning of the method, I want to check if either input string is null or an empty string, and if it is, I return false.
This is the relevant code block -
private static boolean isAnagram(String a, String b) {
System.out.println(a + " " + b);
if( a == null || b == null || a.equals("") || b.equals("") ) {
System.out.println("Inside");
return false;
}
HashMap<String, Integer> map1 = new HashMap<>();
HashMap<String, Integer> map2 = new HashMap<>();
The problem is, when I test this method with invalid inputs, like "hello" and "", the if block doesn't seem to execute. I've tried replacing the .equals() method with .isEmpty() and .length() == 0, but no matter which method I use, the if doesn't work.
Using JShell, I've checked that if I create an empty string with "", all these methods work -
jshell> String a = ""
a ==> ""
jshell> a.isEmpty()
$2 ==> true
jshell> a.length()
$3 ==> 0
jshell> a.equals("")
$4 ==> true
jshell> a == null
$5 ==> false
jshell> "" == ""
$6 ==> true
jshell>
jshell> "".equals("")
$7 ==> true
jshell> "".length()
Is there a reason why this way of checking for empty string won't work in an if block?
UPDATE - Complete code on Pastebin
I see that you don't pass one test case, and it does not involve invalid inputs. You've missed one thing, you should take into consideration case sensitivity
a = a.toLowerCase();
b = b.toLowerCase();
Just make your strings lowercase after validation and it should be alright

how does Operators such as NOT(!), AND(&&) etc work in java?

please help me i cant figure out how does the operators(AND, NOT, XOR ,,..ETC) work in java. I know the output of AND and OR but i am clueless at NOT. For example i don't completely understand statement such as a variable != integer(i!= 3). i mean how does the NOT operator work.for example how does NOT work here.
class Demo {
public static void main(String args[]) throws java.io.IOException {
char ch;
do {
System.out.print("Press a key followed by ENTER: ");
ch = (char) System.in.read(); // get a char
} while (ch != 'q');
}
}
if you make some System outs you will figure out:
char ch = 'l';
System.out.print(2 != 3);
--true, they are not equal
System.out.print('q' != 'q');
-- false, they are equals
System.out.print(ch != 'q');
-- true, they are not equals
it means, they != checks if they are exactly the same (be careful in this case is used for primitive types, such as int, char, bool, etc. this operator work differently in objects, such as String)
int x = 4;
int y = 5;
!case a means not case a
x == y means x and y are referencing the same place in memory (to understand what that means, see this question).
x != y is the opposite of the above, and is the same as writing !(x == y) (not x equals y)
case a && case b And operator - Both case a and case b are true.
case a || case b Or operator - Either case a or case b are true.
Here are same examples so everything is clearer:
1==1 // true, as 1 is equal to 1
2==1 // false, as 1 is not equal to 2.
!true // false, as not true is false.
1!=1 // false, as 1 is equal to one.
!(1==1) // The same as above - exact same output.
// You need the brackets, because otherwise it will throw an error:
!1==1 // Error - what's '!1'? Java is parsed left-to-right.
true && false // false - as not all cases are true (the second one is false)
true || false // rue - as at least one of the cases are true (the first one)
The ! operator is unary. When applied to Boolean values it switches, for example
bool on = true;
System.out.print(!on); //false
System.out.print(on); //true
When used next to an equal sign, it checks if the values are not equal. If they are not equal, it returns true. Otherwise, it returns false. For example,
int two = 2;
int three = 3;
System.out.print(two != three);
//returns true, since they are not equal
System.out.print(two == three);
//returns false, since they are not equal

Java: == in print statement gives different answers [duplicate]

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

strange behavior of == in Java

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.

A quiz taken in a data structure class

Wanted an explanation on the results of question 1.
***1. What is the output of the following method?
public static void main(String[] args) {
Integer i1=new Integer(1);
Integer i2=new Integer(1);
String s1=new String("Today");
String s2=new String("Today");
System.out.println(i1==i2);
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
System.out.println(s1!=s2);
System.out.println( (s1!=s2) || s1.equals(s2));
System.out.println( (s1==s2) && s1.equals(s2));
System.out.println( ! (s1.equals(s2)));
}
Answer:
false
false
true
true
true
false
false
Integer i1=new Integer(1);
Integer i2=new Integer(1);
String s1=new String("Today");
String s2=new String("Today");
// do i1 and 12 point at the same location in memory? No - they used "new"
System.out.println(i1==i2);
// do s1 and s2 point at the same location in memory? No - the used "new"
System.out.println(s1==s2);
// do s1 and s2 contain the same sequence of characters ("Today")? Yes.
System.out.println(s1.equals(s2));
// do s1 and s2 point at different locations in memory? Yes - they used "new"
System.out.println(s1!=s2);
// do s1 and s2 point to different locations in memory? Yes - they used "new".
// Do not check s1.equals(s2) because the first part of the || was true.
System.out.println( (s1!=s2) || s1.equals(s2));
// do s1 and s2 point at the same location in memory? No - they used "new".
// do not check s1.equals(s2) because the first part of the && was false.
System.out.println( (s1==s2) && s1.equals(s2));
// do s1 and s2 not contain the same sequence of characters ("Today")? No.
System.out.println( ! (s1.equals(s2)));
I think the main point is that == compares two object references to see if they refer to the same instance, whereas equals compares the values.
For example, s1 and s2 are two different string instances so == returns false, but they both contain the value "Today" so equals returns true.
Keeping in mind that Integer and String are Objects, the == operator compares the memory addresses of those 2 pointers, not the actual Objects themselves. So the first 2 == are going to be false because i1 is not the same Object as i2. If the initialization was:
Integer i1=new Integer(1);
Integer i2=i1;
Then the first println() would have been true.
The s1.equals(s2) is the proper way to compare equality in Objects. The String.equals() method will check for string equality, so "Today" and "Today" are equal strings.
The s1!=s2 is true since s1 and s2 are different Objects, similar to the i1 and i2 issue with ==
The rest should be pretty straightforward boolean operations.
Which result(s) in particular? Does this help?

Categories