当前位置: 首页 > news >正文

在Java中,==和equals的区别,以及重写equals()方法还要重写hashCode()方法

1. ==和equals的区别?

  • 对于基本类型

        ==判断两个值是否相等,基本类型没有equals()方法

  • 对于引用类型

        == 判断两个变量是否引用同一个对象,

        对于没有重写的equals()方法,比较的是引用类型的变量所指向的对象的地址;

        对于重写的equals()方法,比较的是所指向的对象的内容

equals()源码解析

 * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

从源码中知道,equals()方法存在于Object类中,因为Object类是所有类的直接或间接父类,也就是说所有的类中的equals()方法都继承自Object类,而通过源码我们发现,Object类中equals()方法底层依赖的是==,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用==的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,equals方法进行了重写则是用来比较指向的对象所存储的内容是否相等。

2. 重写equals()方法为什么还要重写hashCode()方法

hashCode()

hashCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。

在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象散列值也相等。

下面的代码中,新建了两个等价的对象,并将它们添加到 HashSet 中。我们希望将这两个对象当成一样的,只在集合中添加一个对象,但是因为 EqualExample 没有实现 hasCode() 方法,因此这两个对象的散列值是不同的,最终导致集合添加了两个等价的对象。

EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(set.size());   // 2

举个例子,比如将对象添加到HashSet中,HashSet会先计算对象的hashCode中来判断对象添加的位置,同时也会与该位置其他已经加入的对象的hashCode值进行比较,如果没有相符合的hashCode,那么该对象就没有出现;但是如果有相同的hashCode值的对象,就会调用equals方法来比较hashCode值相等的对象是否相等。如果hashCode值相等且对象相等,就不会重复添加对象;如果hashCode值相等且对象不相等,就会重新散列其他位置。

比如上面代码中,判断对象相等后,对象相同,equals方法会被覆盖,也就是会被重写,所以对象存在哈希表的位置也会改变,重新赋予对象在哈希表中的位置。如果equals方法重写了,不重写hashCode方法,对象是根据hashCode的存储地址形成的一个哈希值,就会造成相同的对象散列到不同位置(正确的应该是相同的对象散列相同的位置)造成地址不能覆盖的问题。

3. 总结

hashCode()和equals()的联系

    (1)如果两个对象相等,则hashCode一定是相等的。

        对象相等:对象的内容相等,且指向同一个位置地址

    (2)两个对象相等,调用equals方法返回的是true

       分为两种情况:

        <1>类重写了equals方法,比较的是内容相等,但是对象相等hashCode值一定是相同的。

        <2>类没有重写equals方法,比较的是对象的地址已经相等,内容也相等,所以是返回的true

    (3)两个对象有相同的hashCode值,他们不一定相同

             因为hashCode值只是确保地址相同,不一定是对象的内容相等。

    (4)所以equals方法如果被重写,hashCode方法也必须被重写,否则造成地址不统一的问题

相关文章:

  • 计算机知识科普问答--12 (56-60)
  • 【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新
  • 使用Microsoft Visual Studio Installer Projects 2022打包桌面程序
  • NoSQL数据库实战派
  • springboot实战学习笔记(2)
  • Thinkphp5 + Swoole实现邮箱异步通知
  • 【Linux 从基础到进阶】Docker 容器技术基础与应用
  • 【两方演化博弈代码复现】:双方演化博弈的原理、概率博弈仿真、相位图、单个参数灵敏度演化
  • Unity程序基础框架
  • pytest 接口测试
  • 深度挖掘| 如何高效实现Cloudera 安装之基础环境搭建
  • Web3入门指南:从基础概念到实际应用
  • C++第二讲:类和对象
  • Linux中的简单命令2
  • C++系列-STL中搜索相关算法
  • C++二叉搜索树学习
  • 【C/C++】涉及string类的经典OJ编程题
  • Redis 数据类型
  • SpringBoot开发——获取HTTP请求头(Header)的三种方法
  • chattr:修改文件的特殊属性
  • 第12届警博会在即:一批便民利企装备亮相,规模创历史新高
  • 上海工匠学院首届学历班56人毕业,新一届拟招生200人
  • 美国再工业化进程需要中国的产业支持
  • 呼和浩特推进新一轮国企重组整合:杜绝一项目一公司、一业务一公司
  • 中国证监会印发2025年度立法工作计划
  • 东莞“超级”音乐节五一出圈背后:文旅热力何以澎湃经济脉动