They're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.
For instance:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
Answer from T.J. Crowder on Stack OverflowThey're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.
For instance:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
In addition to the accepted answer (https://stackoverflow.com/a/4501084/6276704):
Since Java 1.7, if you want to compare two Objects which might be null, I recommend this function:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
This class consists of static utility methods for operating on objects. These utilities include null-safe or null-tolerant methods for computing the hash code of an object, returning a string for an object, and comparing two objects.
Since: 1.7
Videos
When I type
string1 == string2
IntelliJ tells me to switch to equals(), which it says is null-safe.
But is == operator not null-safe?
I tried null == "abc", "abc" == null, null == null, but they consistently gave me right false false true.
What am I missing here?
I generally use a static utility function that I wrote called equalsWithNulls to solve this issue:
Copyclass MyUtils {
public static final boolean equalsWithNulls(Object a, Object b) {
if (a==b) return true;
if ((a==null)||(b==null)) return false;
return a.equals(b);
}
}
Usage:
Copyif (MyUtils.equalsWithNulls(s1,s2)) {
// do stuff
}
Advantages of this approach:
- Wraps up the complexity of the full equality test in a single function call. I think this is much better than embedding a bunch of complex boolean tests in your code each time you do this. It's much less likely to lead to errors as a result.
- Makes your code more descriptive and hence easier to read.
- By explicitly mentioning the nulls in the method name, you convey to the reader that they should remember that one or both of the arguments might be null.
- Does the (a==b) test first (an optimisation which avoids the need to call a.equals(b) in the fairly common case that a and b are non-null but refer to exactly the same object)
You will need to check atleast one is not null before doing equals method -
Copyif(s1 == s2 || (s1!=null && s1.equals(s2))) {
System.out.println("WORKING :)");
}
here s1==s2 will work incase of null==null . But if even one is not null, then you need to check atleast s1 before doing equals.
Update: As edited by @'bernard paulus', if you are using Java 7, you can use java.util.Objects.equals(Object, Object)