摘要:小概与,这三个操作在程序当中满地都是,特别是容器里,如中的哈希映射与搜索元素就是根据和判断的,所以如何正确的理解和使用显得非常重要,并且在封装类的时候,十分建议通通重写我们先要知道这个概念,每个线程都有属于自己的虚拟机栈,虚拟机栈中的元素我
小概
==,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
阅读原文:不同时重写equals和hashCode又怎样! 可能一问到equals和hashCode相关的问题,就会有人讲他们的自反性,对称性,一致性,传递性等几条约定了,此时我不得不佩服,这么多约定竟然都能记得,但我不知道你是不是真的理解呢。 我不同时重写又能如何呢? showImg(https://segmentfault.com/img/remote/1460000018795219); 我...
摘要:而这次在一的一方实体里重写基类的和方法做去重,感觉用的代码量减少了,又能提高效率,所以我这里对这两个方法做些自己的理解。不相等的两个对象,不一定不相等。不相等,那么是一定不等的。文章若有错误之处,欢迎指出。 昨天写hibernate一对多查询的时候,用set集合来储存值,我们都知道java中List集合是有序,可重复的,Set集合是无序,不可重复的。所以当时写这个查询的时候果断用Set...
摘要:无论在中出现什么,都可以认为它是对象除了八大基本数据类型。让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。但是要注意的是方法调用后,被唤醒的线程不会立马获得到锁对象。主要的区别在于在释放同时,释放了对象锁的控制。 前言 五一回家又断更了一个放假时间了~~~ 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!...
摘要:语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。有针对不同系统的特定实现,,,目的是使用相同的字节码,它们都会给出相同的结果。项目主要基于捐赠的源代码。 本文来自于我的慕课网手记:Java编程中那些再熟悉不过的知识点,转载请保留链接 ;) 1. 面向对象和面向过程的区别 面向过程 优点: 性能比面向对象高。因为类调用时需要实例...
摘要:根据的重新计算值。如果这两个的通过比较返回,新添加的将覆盖集合中原有的,但不会覆盖。如果这两个的通过比较返回,新添加的将与集合中原有形成链,而且新添加的位于链的头部具体说明继续看方法的说明。 关于hashCode hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的. 1.hashcode是用来...
阅读 3397·2021-11-24 10:30
阅读 3267·2021-11-22 15:29
阅读 3703·2021-10-28 09:32
阅读 1251·2021-09-07 10:22
阅读 3334·2019-08-30 15:55
阅读 3617·2019-08-30 15:54
阅读 3491·2019-08-30 15:54
阅读 2830·2019-08-30 15:44