Why
Sometimes we will need to override the equals()
and hashcode()
methods in a class in order to realize some specific functions. For example, if we have a class Person as below.
class Person {
public long id;
public double salary;
}
If we have a list of Person object, we would like to remove a person from the list. However, we only know the id of this person. In order to use simple code as list.remove(person)
, we would need to override equals()
and hashcode()
. Because remove()
estimates with (o==null ? get(i)==null : o.equals(get(i)))
.
How
The equals()
method is relatively easy to override, see the example as below.
The hashCode()
method should take care all key fields in this class. The steps to calculate it is as below.
- Save a non-zero integer in
result
- For every key fields, perform following steps to calculate
c
:- If
boolean
, calculate(f ? 0 : 1)
- If
byte
,char
,short
orint
, calculate(int) f
- If
long
, calculate(int) (f ^ (f >>> 32))
- If
float
, calculateFloat.floatToIntBits(f)
- If
double
, calculateDouble.doubleToLongBits(f)
, then repeat what forlong
- If an object ref, call its
hashCode()
, return 0 ifnull
- If an array, treat every element as key field
- Finally for all,
result = 37 * result + c
- If
- Return
result
For the Person class example, the methods are overriden as below.
class Person {
public long id;
public double salary;
@Override
public boolean equals (Object other) {
//step 1
if (this == other) {
return true;
}
//step 2
if (!(other instanceof Person)) {
return false;
}
//step 3
Person that = (Person) other;
return (this.id == that.id);
}
@Override
public int hashCode() {
int result = 17;
int c = (int) (this.id ^ (this.id >>> 32));
result = 37 * result + c;
return result;
}
}