对象作为HashMap的键为什么要重写equals方法和hashCode方法
package com.zzy.xuexi_utils.pojo;
import java.util.Objects;
/**
* @author zzy
* @create 2021/5/4
*/
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(getName(), user.getName()) &&
Objects.equals(getAge(), user.getAge());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
}
idea快速生成方法快捷键 ctrl+insert
首先看下这几个方法
1: toString方法
System.out.println(user1);
//使用默认toString方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
输出 com.zzy.xuexi_utils.pojo.User@30f39991
//重写toString方法
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
输出 User{name='zzy', age=18}
2: hashCode()方法
默认的toString和equals方法都会用hashCode方法
//默认hashCode方法是根据对象的内存地址经哈希算法得来,java内存地址无法直接得到
public native int hashCode();
//重写的hashCode方法,根据属性值hash
public int hashCode() {
return Objects.hash(getName(), getAge());
}
3:equals()方法
//默认的equals方法,内部使用 == 比较地址值
public boolean equals(Object obj) {
return (this == obj);
}
//重写的equals方法,比较的是属性值
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(getName(), user.getName()) &&
Objects.equals(getAge(), user.getAge());
}
4 . == 比较符
基本数据类型 比较的是值
引用数据类型 比较的是地址值
5.对象作为hashMap的键为什么要重写equals方法和hashCode方法
User user1 = new User("zzy",18);
User user2 = new User("zzy",18);
hashMap<User, String > map = new HashMap<>();
map.put(user1,"22");
map.put(user2,"23");
我们在逻辑上认为 user1和user2,名字相同,年龄相同就是同一个对象
但是在代码中user1和user2有着不同的地址值,不能去重
我们知道hashMap.put()的过程是先进行hashCode判断,如果hash值相同,在进行equals判断
因为hashCode相率高,但是hshCode相同,值不一定相同
1:hashCode和equals都不重写
hashCode默认方法,是地址值的hash值,user1和user2不相同,map不能去重
2: hashCode不重写和equals重写
hashCode默认方法,是地址值的hash值,user1和user2不相同,map不能去重
3:hashCode重写和equals不重写
重写hashCode方法,根据属性值hash,相同,然后equals默认方法比较的是地址值,不相同.因为地址值不同,map还是不能去重
综上:使用User做map的键必须重写equals方法和hashCode方法