equals方法和hashCode方法
创建User类,重写它的equals方法和hashCode方法。
public class User {
private Integer userId;
private String account;
private String key;
private Character sex;
private Integer age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(userId, user.userId) &&
Objects.equals(account, user.account) &&
Objects.equals(key, user.key) &&
Objects.equals(sex, user.sex) &&
Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(userId, account, key, sex, age);
}
}
equals 方法解析:
if (this == o) return true; 当这个对象等于它自己的时候,返回true; 例如user.equals(user);
if (o == null || getClass() != o.getClass()) return false; 判断传入对象是否为null或是否是别的类型,返回flase; 例如user.equals(null);
User user = (User) o; 将传入对象转换为User对象。
return 之后的返回值 为每个属性值的比较。
当然 是调用了Objects的equals方法,而调用什么方法,取决于什么参数,如果参数都是String类型,则会调用String类的equals方法,因为String是Object的子类。【即父类声明调用子类方法】
那就看看Objects的equals方法怎么实现的
点开equals的源码:
(a ==b)||(a != null && a.equals(b));先比较a与b的内容和内存地址是否一致,再比较 a的值是否为空与e.equals(b);
点开e.equals(b)中的equals中的源码:
可以看出,这里是判断这两个值的内存地址是否相等。
也就是说。如果是基本类型,则可以按照(a == b)的方式直接判断,如果是引用类型,则按照equals方法进行比较。
hashCode 方法解析:
点看hash方法,查看源码:
这里调用了Arrays的hashCode方法,
但是注意参数列表中存在
(Object… valuse)
其中 … 表示不确定参数个数,所有用了 … 来代替所传来的参数
继续点看hashCode(values)的源码:
在这段的参数列表中也可以看出, 在调用Arrays.hashCode(valuse)方法时,传递的参数也是以数组的形式记录了。
第一个if判断 : 当a[]为空时,则哈希码就是0;
如果不为空,则执行下面的循环部分,
带参数解释下:
假定这个对象为 User u = new User(“userId”,“account”,'key",“sex”,“age”);
那么这个数组长度就是5,则会进行5次循环
第一次循环:result = 31 * 1 + (userId == null ?0 : userId.hashCode());
第二次循环:result = 31 * result【注:即第一次循环的result】+(userId == null ?0 : userId.hashCode());
以此类推
得到整个对象的hash值。
应用:重写equals方法和hashcode主要使用在Map中,当引用类型为key时,因为key是唯一的,不可重复的,故会比较两个对象是否相等。再判断是覆盖还是新增。