【Java】HashCode方法重写注意事项

本文详细介绍了Java中的HashCode方法,包括其用途、hashCode和equals方法的关系,以及它们在哈希表中的应用。强调了equals和hashCode的处理规则,并通过示例代码展示了如何重写这两个方法。同时提到了MD5加密中的哈希算法概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashCode方法

  1. HashCode方法是属于Object父类提供的方法,HashCode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable提供的哈希表
  2. HashCode的常规协定是:在Java应用程序执行期间,在同一个对象上多次调用hashCode方法时,必须一致地返回相同的整数。
  3. HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode是用来在散列存储结构中确定对象的存储地址的
  4. 如果equals方法比较相等,则HashCode值也一定相等,但是HashCode值相等不代表equals比较也相等
  5. 如果类中重写了 equals 方法 必须要重写 HashCode 方法

【强制】关于 hashCode 和 equals的处理,遵循如下规则:

  • 只要重写 equals,就必须重写 hashCode
  • 因为Set 存储的是不重复的对象,依据 hashCode和equals 进行判断,所以 Set存储的对象必须重写这两个方法
  • 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和equals

   说明:String 因为重写了hashCode 和 equals 方法,所以我们可以愉快地使用 String 对象作为  Key 来使用

示例代码

package com.collection.Demo10;

import java.util.Objects;

public class MayktEntity {
    private String name;
    private Integer age;

    public MayktEntity(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        //先判断两个对象内存地址是否相同
        if (this == o) return true;
        //如果第二的对象为null或者 两个类型不相等  返回false
        if (o == null || getClass() != o.getClass()) return false;
        //比较两个对象的成员属性值是否相等
        MayktEntity that = (MayktEntity) o;
//        return (this.name.equals(that.name)) && (this.age.equals(that.age));//等价与下一行
        return Objects.equals(name, that.name) && Objects.equals(age, that.age);
    }

    /**
     * public static boolean equals(Object a, Object b) {
     * return (a == b) || (a != null && a.equals(b));
     * }
     * <p>
     * public boolean equals(Object obj) {
     * return (this == obj);
     * }
     */

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
//        return this.name.hashCode() + this.age.hashCode();//这行是将两个hash值相加,可以看到两个对象的hash是否相等,
        //但与上面一行不等价
    }
}
package com.collection.Demo10;

public class Test02 {
    public static void main(String[] args) {
        /**
         * equals作用:equals就是在比较两个对象的值是否相等(误区)
         * equals属于Object父类中 默认的情况下 在比较两个对象的内存地址是否相同
         * 如果想要能够实现比较两个对象中成员属性值是否相等 需要重写父类中的equals()
         */
        String str1 = "mayikt";
        String str2 = "mayikt";
        System.out.println(str1 == str2);//true
        System.out.println(str1.equals(str2));//true 问题:这里的equals为什么是为true?
        //∵ String类中 重写父类中的equals() 比较两个字符串值是否相同
        MayktEntity maykt1 = new MayktEntity("mayikt", 22);
        MayktEntity maykt2 = new MayktEntity("mayikt", 22);
        System.out.println(maykt1.equals(maykt2));//false  这里实际上 等价与mayikt1==mayikt2 比较两个对象的内存地址是否相同
        //如果上面在MayiktEntity中重写了equals(),maykt1.equals(maykt2) 结果为 true
        System.out.println(maykt1 == maykt2);//false

        //如果只重写equals,不重写hashCode() 两个值是不一样的
        System.out.println(maykt1.hashCode());//1163157884 重写后:845662570
        System.out.println(maykt2.hashCode());//1956725890 重写后:845662570
    }
}

package com.collection.Demo10;

public class Test03 {
    public static void main(String[] args) {
        /**
         * HashCode?
         * hashCode 属于 object父类中 Java虚拟机提供 给每个对象生成一个 hashCode值 整数类型(int)
         * hashCode值生成规则:堆内存地址转化成整数类型
         */
        String str1 = "mayikt1";
        String str2 = "mayikt2";
        String str3 = "mayikt2";
        System.out.println(str1.equals(str2));//false
        System.out.println(str1.hashCode());//845661636
        System.out.println(str2.hashCode());//845661637
        System.out.println(str3.hashCode());//845661637
        Object o = new Object();
        System.out.println(o.hashCode());//1163157884
        /**
         * 1.如果使用equals方法比较两个对象相等,则HashCode值一定相等
         * 2.但是两个对象的HashCode值相等 不代表使用equals比较也相等
         * 3.如果两个对象的HashCode值相等,但是值是不同的 专业术语:Hash冲突问题
         * HashMap集合底层源码 根据该对象的HashCode值计算存放到数组中index位置
         */
        String strA = "a";
        Integer int97 = 97;//这里只可以用Integer 引用类型,int类型 不可以使用hashCode
        //整数类型 包装类Integer hashCode值是多少呢?——就是该整数类型值 97
        System.out.println(strA.hashCode());//97
        System.out.println(int97.hashCode());//97
        System.out.println(strA.equals(int97));//false
    }
    /**
     * MD5 加密底层算法——hash算法
     * 相同的内容 做MD5 得到md5值是一样的
     */
}

下一篇文章:HashMap常见的面试题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值