In the below example, I am expecting equals()
to return true
:
public class flower {
String flower;
public flower (String flower) {
this.flower = flower;
}
public static void main(String[] args) {
flower one = new flower("Flower");
boolean isSame = false;
if(one.equals("Flower")) {
isSame = true;
}
System.out.print(isSame);
}
}
However, the result I get is false
... is it because I'm comparing an object with a String
? I read the equals()
method and is said to compare String
s with Objects
. Why am I getting the result as false
although they are the same?
The short answer: You need to override the implementation of equals()
in your Flower
(note: capital F
) class. This will do something you like to do:
@Override
public boolean equals(Object o) {
return (o instanceof Flower && ((Flower)o).flower.equals(flower)) ||
(o instanceof String && o.equals(flower));
}
@Override
public int hashCode() {
return flower.hashCode();
}
Overriding hashCode()
together with equals()
is good form: generally, the 'attributes' (e.g. fields) you pick for doing an equals()
should be used in your hashCode()
calculation too. In layman terms, they should 'agree' with each other.
The big/major/severe problem, as pointed out by practically everyone here I presume, is that equals()
is meant to be symmetric:
It is symmetric: for any non-null reference values
x
andy
,x.equals(y)
should return true if and only ify.equals(x)
returns true.
And unfortunately for your Flower
class, String.equals(Object)
is defined as such:
The result is
true
if and only if the argument is notnull
and is aString
object that represents the same sequence of characters as this object. (emphasis mine)
This means that no String
will ever return true
when you pass a Flower
object to equals()
.
Sure, you can still go against the convention, but you'll likely run into bugs - minor or major - very soon when you learn more about the language, e.g. the Collection
classes.
Therefore: avoid such comparisons with equals()
.