实现对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