为什么重写 equals(equals 与 == 的区别),为什么重写 equals 通常需要重写 hashCode (equals 与 hashCode 的区别)
原创
©著作权归作者所有:来自51CTO博客作者茅坑的小石头的原创作品,请联系作者获取转载授权,否则将追究法律责任
1. 先上结论
1.1. 为什么重写 equals(equals 与 == 的区别)
- equals用于比较对象的所有属性是否都相等
- 自定义的类会继承 Object,Object 的 equals 方法是==,== 比较的是地址,不符合规范,所以需要重写。
1.2. 为什么重写 equals 通常需要重写 hashCode (equals 与 hashCode 的区别)
- hashCode用于返回对象的哈希码值。支持这种方法是为了散列表,如HashMap、Set。
- 自定义的类会继承 Object,Object 的 hashCode 返回的是对象内存地址,不符合规范,所以需要重写。
- 两个对象 equals,那么 hashCode 值肯定相等;两个对象 hashCode值相等 不一定 equals。
- HashMap、Set使用hashCode确定key的位置的。使用hashCode是可以大大提高效率。因为如果用 equals ,在插入新数据时需要和前面每个去比较;如果用hashCode,会先获取位置直接判断有没有值,没有直接插入数据,hashCode相同时(小概率)才调用equals方法进一步确认
2. 测试代码
public class User {
private int id;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
if (id != user.id) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
/** 全参构造器 */
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
public class UserTest {
public static void main(String[] args) {
User u1 = new User(1, "张三");
User u2 = new User(1, "张三");
System.out.println(u1 == u2);
System.out.println(u1.equals(u2));
System.out.println(u1.hashCode() == u2.hashCode());
}
}
输出结果总结
| 都不重写
| 重写 equals
| 重写 hashCode
| 都重写
|
u1 == u2
| false
| false
| false
| false
|
u1.equals(u2)
| false
| true | false
| true |
u1.hashCode() == u2.hashCode()
| false
| false
| true | true |