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