资讯专栏INFORMATION COLUMN

几分钟理解 Jdk - ==,hashCode() 与 equals()

CNZPH / 1659人阅读

摘要:小概与,这三个操作在程序当中满地都是,特别是容器里,如中的哈希映射与搜索元素就是根据和判断的,所以如何正确的理解和使用显得非常重要,并且在封装类的时候,十分建议通通重写我们先要知道这个概念,每个线程都有属于自己的虚拟机栈,虚拟机栈中的元素我

小概

==,hashCode() 与 equals() ,这三个操作在 Java 程序当中满地都是,特别是容器里,如 Map 中的哈希映射与搜索元素就是根据
hashCode() 和 equals() 判断的,所以如何正确的理解和使用显得非常重要,并且在封装类的时候,十分建议通通重写

我们先要知道这个概念,每个线程都有属于自己的 虚拟机栈,虚拟机栈中的元素我们称之为 栈帧,每运行一个方法时,虚拟机会为这个方法创建一个栈帧,并入栈,方法结束后便出栈

那么我们操作的变量有两种

局部变量:存在当前栈帧的局部变量表里,如果是基本数据类型便是值的大小,如果是对象便是一个指向堆内存中对象地址的引用

全部变量:存在方法区中,存储规则一样

所以我们比较的,是 基本数据类型的大小引用地址

a == b

比较规则

当a,b 为对象时,表示两者 引用地址 是否相同,即堆内存中地址是否相同

当a,b 为基本数据类型时,表示两者 数据大小 是否相等

a.equals(b)

假设 a 的对象类型为 A

比较规则

a,b 只能为对象,表示两者 对象属性 是否相等,如 String 就是比较内部维护的 char[] 数组每一个字符是否相等

为了简化比较复杂度,往往会先判断 a == b,如果它们都指向同一个地址,那么两者内容肯定一样,则不需要逐一比较对象内容中的值

我们可以认为,== 和 equals 的推导关系是 充分不必要

== 成立则 equals 成立

equals 成立,== 不一定成立

如何比较属性

比如区分两个学生是否是同一个学生,我们其实只需要查看他们的学号是否相同就行了

也就是我们应该比较能唯一标识这个对象的一个甚至多个对象属性,情况完全视不同对象而定

如果 A 未重写 equals()

如果 A 未重写时,调用的是父类的 equals(),还未重写,会检查到 Object,而 Object 是如下比较的

    public boolean equals(Object obj) {
        return (this == obj);
    }

利用 == 号比较对象内容是否相等未必有点草率,因此我们对这个方法应当十分谨慎

如何重写

重写时需注意应当满足如下规则,摘自 《Effective Java》

自反性:x.equals(x)必须返回true

对称性:x.equals(y)与y.equals(x)的返回值必须相等

传递性:x.equals(y)为true,y.equals(z)也为true,那么x.equals(z)必须为true

一致性:如果对象x和y在equals()中使用的信息都没有改变,那么x.equals(y)值始终不变

非null:x不是null,y为null,则x.equals(y)必须为false

在这里建议按以下规则重写

建议判断 a == b,省去没必要的比较

建议先判断 b instanceOf A,再做能能标识唯一对象的一个或多个属性的比较

建议考虑 super.equals(b)

a.hashCode()

该方法返回的是对象的哈希值,主要应用于哈希容器映射时,将所有类型对象映射成整数

如何重写

在这里建议按以下规则重写

建议对能标识唯一对象的一个或多个属性进行 hashCode() 重写

建议利用 jdk 基础封装类的 hashCode()

建议考虑 super.equals(b)

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

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

相关文章

  • 不同时重写equalshashCode又怎样

    阅读原文:不同时重写equals和hashCode又怎样! 可能一问到equals和hashCode相关的问题,就会有人讲他们的自反性,对称性,一致性,传递性等几条约定了,此时我不得不佩服,这么多约定竟然都能记得,但我不知道你是不是真的理解呢。 我不同时重写又能如何呢? showImg(https://segmentfault.com/img/remote/1460000018795219); 我...

    nifhlheimr 评论0 收藏0
  • 关于equalshashCode方法的一些理解

    摘要:而这次在一的一方实体里重写基类的和方法做去重,感觉用的代码量减少了,又能提高效率,所以我这里对这两个方法做些自己的理解。不相等的两个对象,不一定不相等。不相等,那么是一定不等的。文章若有错误之处,欢迎指出。 昨天写hibernate一对多查询的时候,用set集合来储存值,我们都知道java中List集合是有序,可重复的,Set集合是无序,不可重复的。所以当时写这个查询的时候果断用Set...

    ctriptech 评论0 收藏0
  • Object对象你真理解了吗?

    摘要:无论在中出现什么,都可以认为它是对象除了八大基本数据类型。让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。但是要注意的是方法调用后,被唤醒的线程不会立马获得到锁对象。主要的区别在于在释放同时,释放了对象锁的控制。 前言 五一回家又断更了一个放假时间了~~~ 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!...

    anquan 评论0 收藏0
  • Java编程中那些再熟悉不过的知识点(持续更新)

    摘要:语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。有针对不同系统的特定实现,,,目的是使用相同的字节码,它们都会给出相同的结果。项目主要基于捐赠的源代码。 本文来自于我的慕课网手记:Java编程中那些再熟悉不过的知识点,转载请保留链接 ;) 1. 面向对象和面向过程的区别 面向过程 优点: 性能比面向对象高。因为类调用时需要实例...

    taowen 评论0 收藏0
  • 重新详尽的理解HasMap

    摘要:根据的重新计算值。如果这两个的通过比较返回,新添加的将覆盖集合中原有的,但不会覆盖。如果这两个的通过比较返回,新添加的将与集合中原有形成链,而且新添加的位于链的头部具体说明继续看方法的说明。 关于hashCode hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的. 1.hashcode是用来...

    maxmin 评论0 收藏0

发表评论

0条评论

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