对象作为HashMap的键为什么要重写equals方法和hashCode方法

对象作为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方法
上一篇:在Android Studio 0.5.2中使用ArcGIS Android SDK


下一篇:深入探究Java中hashCode()和equals()的关系