0%

在Java8中实现equals和hashCode

实现对Java中的自定义类型的比较是一个基础知识,即重载Object的equals和hashCode方法,且两个方法的行为要一致(即两个对象equals为true时hashCode也要一样,反之亦然)。 平常也没有太注意,最近用到了还感觉有点意思,遂怒水一文。 实现这个有几种方法: 1. 手写,判空、比较每个属性; 2. 在IDE中右击,generate... 3. 手写,使用Guava中的Objects下的方法; 4. 手写,使用Java8中的Objects下的方法;

使用第4种(其实第2种现在生成的代码也和第4种一致)方法生成的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
Student that = (Student)o;
return Objects.equals(id, that.id) &&
Objects.equals(age, that.age);
}

@Override
public int hashCode() {
return Objects.hash(id, age);
}

Guava和Java8的方法实现是比较一致的,在生成hashCode时都用了“31”作为算子,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
public static int hashCode(Object a[]) {
if (a == null)
return 0;

int result = 1;

for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());

return result;
}

选31的第一个原因是它是一个质数,第二所说是因为其据于被JVM所优化:31 * i = (i << 5) - i