资讯专栏INFORMATION COLUMN

Java Object对象的hashcode和equals方法

chnmagnus / 3400人阅读

摘要:在中对象是一切对象都会自动继承的一个类,在这个类中定义的属性和方法可以说是每个类都必须的。这里有必要说说这里对象里面的几个方法返回该对象的哈希码值。这些基于表的集合,只能要求被存放的对象实现自己的方法,保证的均匀性。

Object

在Java中Object对象是一切对象都会自动继承的一个类,在这个类中定义的属性和方法可以说是每个类都必须的。

这里有必要说说这里对象里面的几个方法

hashCode()

返回该对象的哈希码值。

为什么需要这个方法

我在面试时,问一些基本的Java知识时,很多时候会问到这个问题。但大多数人,没有很明白的说明这个问题。

首先这个问题,还是先要说下hash表的数据结构,如果还想复习下关于hash表结构的知识,可以参看这篇文章,写的不错:http://www.cnblogs.com/dolphin0520/archive/2012/09/28/2700000.html

这个方法的存在主要是配合一些基于hash表的数据结构的集合,像HashMap。在这些基于hash结构的数据集合中,存放的对象要有自己的hashCode方法,除了String类型。以HashMap为例:

    /**
     * Retrieve object hash code and applies a supplemental hash function to the
     * result hash, which defends against poor quality hash functions.  This is
     * critical because HashMap uses power-of-two length hash tables, that
     * otherwise encounter collisions for hashCodes that do not differ
     * in lower bits. Note: Null keys always map to hash 0, thus index 0.
     */
    final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
        h ^= k.hashCode();
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

HashMap在存放或者检索数据时,都会先去计算的key的hash值。这些基于hash表的集合,只能要求被存放的对象实现自己的hash方法,保证hash的均匀性。在jdk中,为了保证一个通用的计算hash的方法,jvm采用将对象的内部地址转换成一个整数来实现
我们也可以根据自己的逻辑修改hashcode方法

equals(Object o)

用于测试某个对象是否同另一个对象相等

在Java语言中要比较两个对象是否相等,有时只用"=="是不行的,还有这个equals方法。比如在Java中比较两个字符串相等,那就必须使用equals方法
因为,==计算表达式在判断引用对象时,只是去判断内存地址引用是否一样,而equals方法才会去判断内存的值是否一样或是按照自实行逻辑去判断。

必要时重写equals

equals方法在很多地方会调用,包括我们直接调用equals方法,还有判断集合对象是否相等时的间接调用。在这种间接调用时,我们一般都会去重写它的equals方法。
比如,有个User对象,我们认为User的id相等就是同一个对象

  Public class User{
      public long id;
      public String name;
  }

现在有个两个存放User对象的集合userListA、usersListB,这时我们判断这俩集合是否相等,其目的就是判断这俩集合存放的对象是否相等(只简单要求List各个索引位置的User对象相等)。
那这是我们就必须重写User对象的equals方法

   @Override
   public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       User user = (User) o;
       return id == user.id;
   }

重写equals方法的要求:

自反性:对于任何非空引用x,x.equals(x)应该返回true。

对称性:对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。

传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。

一致性:如果x和y引用的对象没有发生变化,那么反复调用x.equals(y)应该返回同样的结果。

非空性:对于任意非空引用x,x.equals(null)应该返回false。

重写了equals方法要不要重写hashCode方法

当我们重写hashcode方法时,都会有一套模板,我们使用到的编辑器一般都会支持基于模板自动生成。如果留心,你会发现当你使用这个功能时重写equals方法会自动也把hashcode方法重写。

在Java规范中,要求:

如果a.equals(b),那么a和b的hashcode方法一定要相等,但a和b不相等时,hashcode方法可以相等也可以不相等。所以当我们重写了它的equals方法后,最好遵从这份规范,修改它的hashcode方法。

equals 方法未来会不会舍弃

如果==这种计算,不仅仅是看内存地址是否相等,如果在不相等时也去判断下不同内存地址下的值也是相等,就返回true,那有一天Object对象会不会就会舍弃这个equals方法

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64720.html

相关文章

  • Java Object方法分析

    摘要:类方法分析声明文章均为本人技术笔记,转载请注明出处类简介类是所有类的父类,在中只有基本数据类型不是对象。对于所有数组类型对象类型基本数据类型数组都继承于类方法类中通过判断两个对象是否具有相同引用,从而判断两个对象是否相同子类只要重写方法,就 Java Object类方法分析 声明 文章均为本人技术笔记,转载请注明出处https://segmentfault.com/u/yzwall ...

    zhisheng 评论0 收藏0
  • 【码艺杂谈】Java相同与不同

    摘要:如果根据方法得到两个对象不相同,那么两个对象的方法的结果不一定不相同,我们可以利用这一点来提高散列表的性能。最后回到文章开头的问题,如何判断两个对象或值是否相同这个问题其实有两方面的含义,一方面是判断的方法,另一方面是判断的效率。 Java中有很多场景需要判断两个对象或者两个值,那么 判断是否相同的依据是什么? 如何判断是否相同呢? 为了解释这个问题,我们从Java语言的根说起,那...

    xingqiba 评论0 收藏0
  • 好用java.util.Objects类

    摘要:好用的类在中,新增了一个工具类,就是类。事实上,我们进行比较的对象,除了引用对象之外,就是自动装箱后等类型了。我们在重写时,可以参考上面的类的写法。 好用的java.util.Objects类 在jdk1.7中,新增了一个工具类,就是java.util.Objects类。它有3个简单的封装方法,对于平常的使用来说挺有用的,分别是:hashCode、equals、toString这3个方...

    heartFollower 评论0 收藏0
  • 谈谈java中几种常见散列算法及解决哈希碰撞方式

    摘要:接下来分析几个常见的实现方式。再哈希法再哈希法,就是出现冲突后采用其他的哈希函数计算,直到不再冲突为止。,其中为不同的哈希函数。 由表及里,循序渐进,请往下看。随手点赞是对作者最大的鼓励!^0^。 什么是哈希表 引用:严蔚敏 《数据结构(C语言版)》中的内容 showImg(https://segmentfault.com/img/bVZlmE?w=800&h=364); 哈希表就是 ...

    沈建明 评论0 收藏0
  • Java equals == 完全解析

    摘要:所以在对象没有重写这个方法时,默认使用此方法,即比较对象的内存地址值。结果为可以发现不管对象的内存地址是否相同并不影响其结果,所以类型比较的是数据值而不是内存地址值。 showImg(https://segmentfault.com/img/bVbqpku?w=800&h=344); 今天朋友突然问到一个问题: 两个对象使用x.equals(y)判断结果为true时,两个对象的hash...

    mikasa 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<