前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈equals、hashcode、==

浅谈equals、hashcode、==

作者头像
崩天的勾玉
发布2021-12-20 17:35:06
6540
发布2021-12-20 17:35:06
举报
文章被收录于专栏:崩天的勾玉崩天的勾玉

==和equals和hashcode是经常遇到但是很重要的内容,希望这篇文章能帮你理清概念。

==

在Java中有八种基本数据类型:float(4 byte), double(8 byte),byte(1 byte), short(2 byte), int(4 byte) , long(8 byte),char(2 byte),boolean。

对于这八种基本数据类型的变量,变量直接存储的是“值”。因此,在使用关系操作符 == 来进行比较时,比较的就是“值”本身。要注意的是,浮点型和整型都是有符号类型的(最高位仅用于表示正负,不参与计算【以 byte 为例,其范围为 -2^7 ~ 2^7 - 1,-0即-128】),而char是无符号类型的(所有位均参与计算,所以char类型取值范围为0~2^16-1)。

对于关系操作符 ==:

  1. 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的值是否相等
  2. 若操作数的类型是引用数据类型,则该关系操作符判断的是左右两边操作数的「内存地址是否相同」。也就是说,若此时返回true,则该操作符作用的一定是同一个对象。

equals

equals方法是基类Object中的实例方法,因此对所有继承于Object的类都会有该方法。「该方法本意是比较内容是否相同」

Object类中equals方法的实现:

代码语言:javascript
复制
  public boolean equals(Object obj) {
    return (this == obj);
  }

在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。

但是,String类重写了equals 方法:

代码语言:javascript
复制
public boolean equals(Object anObject) {   // 方法签名与 Object类 中的一致
    if (this == anObject) {     // 先判断引用是否相同(是否为同一对象),
        return true;
    }
    if (anObject instanceof String) {   // 再判断类型是否一致,
        // 最后判断内容是否一致.
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
}

String类使用equals方法,内部实现分为三个步骤:

  1. 先比较引用是否相同(是否为同一对象),
  2. 再判断类型是否一致(是否为同一类型),
  3. 最后比较内容是否一致。

Java 中所有内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。

equals 重写原则:

  1. 对称性: 如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true” ;
  2. 自反性:x.equals(x)必须返回是“true” ;
  3. 类推性: 如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true” ;
  4. 一致性: 如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true” ;
  5. 对称性: 如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
  6. 任何情况下,x.equals(null)【应使用关系比较符 ==】,永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”

hashcode

在 Java 中,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。(这是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧)。

HashCode 只是在需要用到哈希算法的数据结构中才有用,比如 HashSet, HashMap 和 Hashtable。

要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢? 这就是 Object.equals 方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。 也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。于是,Java采用了哈希表的原理。 这样,我们对每个要存入集合的元素使用哈希算法算出一个值,然后根据该值计算出元素应该在数组的位置。所以,当集合要添加新的元素时,可分为两个步骤:

  1. 先调用这个元素的 hashCode 方法,然后根据所得到的值计算出元素应该在数组的位置。如果这个位置上没有元素,那么直接将它存储在这个位置上;
  2. 如果这个位置上已经有元素了,那么调用它的equals方法与新元素进行比较:相同的话就不存了,否则,将其存在这个位置对应的链表中(Java 中 HashSet, HashMap 和 Hashtable的实现总将元素放到链表的表头)。

一般来讲,equals 这个方法是给用户调用的,而 hashcode 方法一般用户不会去调用,总结来说,「hashcode是系统用来快速检索对象而使用。」

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 崩天的勾玉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ==
  • equals
  • hashcode
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档