Generic classes in java and equals() method: type safety
You can cast obj
to a Pair<?, ?>
and call equals
on first
and second
:
Pair<?, ?> other = (Pair<?, ?>) obj;
return other.first.equals(first) && other.first.equals(second);
This way the type checks will be handled by T.equals
and U.equals
, whatever T
and U
are.
You could write your equals
method like this:
@Override
public boolean equals(Object object) {
boolean equal = false;
if(this == object){
equal = true;
} else if(object instanceof Pair<?, ?>) {
// Check that object is an instance of Pair<?, ?>, this will also null check.
// Then just case object to Pair<?, ?> like.
Pair<?, ?> pair = (Pair<?, ?>) object;
if(((this.first == null && pair.first == null) || (this.first != null && this.first.equals(pair.first))) &&
((this.second == null && pair.second == null) || (this.second != null && this.second.equals(pair.second)))){
equal = true;
}
}
return equal;
The ?
between the <>
is kind of a wildcard, it's actually classed as the unbounded wildcard; which means the type of class has not been specified.
The object instanceof Pair<?, ?>
will check two things, first it will check that the object is not null, so creates null
safety for you and then it will check that the object is of type Pair<?, ?>
.
You can read about wildcards here
As per ntalbs
if you are overriding equals
don't forget to override hashCode
as well.
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashcode;
result = result * prime + (this.first == null ? 0 : this.first.hashCode());
result = result * prime + (this.second == null ? 0 : this.second.hashCode());
return result;
}
Why do I have to override hashCode
when I override equals
?
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
You can use instanceof
to check for the type of your object and then cast it safely.
if(obj instanceof Pair){
Pair other = (Pair) obj;
}