equals和hashcode

1.
String a = "A";
String b = "A";
= 是一个赋值的,而A在内存中有自己本身的hashcode
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode("a"));
System.out.println(System.identityHashCode(b));
本地的的hashcode方法是不行的!

hashcode是根据对象的内存地址经哈希算法得来的。

可以看出每个字符的值是相同的 所以 我们在用==判断相等的时候
其实判断的就是标识值
2
当我们
String str=new String("a");
String str2=new String("a");
System.out.println(str==str2);
此时输出的是false
相当于new对象时 又将 "a"封装了一下 所以通过标示值判断的方法就失效了
3.
equals方法 :源码中给出的注释,意思是,当且仅当二者不为空且字符顺序都相同时,返回真。
看源码,首先使用“==”判断二者标识值是否相同,相同时返回真。

==是判断两个变量或实例是不是指向同一个内存空间
之后利用“instanceof”判断对象是否为字符类,如果不是则返回假。之后的操作便是逐字比较。
4.
hashcode方法:利用ASCII码进行算法运算得出hashcode的方法。
map也是,利用得到的hashcode通过对map大小取mod,hashcode%map.length,得到数组下标,存入
5.
使用非自定义类的时候,hashcode相等,值不一定相等;值相等,hashcode一定相等。
而当使用自定义类求hashcode的时候,即使初始化相同值,最后hashcode也不等。
不重写equals方法,则不能比较自定义类 在使用hashmap的时候就会出现问题
同理适用于hashcode,不重写就无法得出原hash值,也自然无法比较依靠原hashcode找到该数据。

 6.

关于equals和hashcode的重写

只重写equals而不重写hashcode,

那么类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。

7. 其他补充

如果大家要在HashMap的“键”部分存放自定义的对象,一定要在这个对象里用自己的equals和hashCode方法来覆盖Object里的同名方法。

当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。

一个对象多次调用它的hashCode方法,应当返回相同的integer(哈希值)。
两个对象如果通过equals方法判定为相等,那么就应当返回相同integer。
两个地址值不相等的对象调用hashCode方法不要求返回不相等的integer,但是要求拥有两个不相等integer的对象必须是不同对象。

hashCode方法实际上必须要完成的一件事情就是,为该equals方法认定为相同的对象返回相同的哈希值。

Object类中的equals方法区分两个对象的做法是比较地址值,即使用“==”。

而我们如若根据业务需求改写了equals方法的实现,那么也应当同时改写hashCode方法的实现。否则hashCode方法依然返回的是依据Object类中的依据地址值得到的integer哈希值。

String类中对equals方法进行重写扩充了,但是如果此时我们不将hashCode方法也进行重写,那么String类调用的就是来自顶级父类Obejct类中的hashCode方法。

即,对于两个字符串对象,使用他们各自的地址值映射为哈希值。

hashCode方法的重写原则就是保证equals方法认定为相同的两个对象拥有相同的哈希值”。

在java的集合中,判断两个对象是否相等的规则是:
1),判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入2)
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这个问题。)
2),判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)
为什么是两条准则,难道用第一条不行吗?不行,因为前面已经说了,hashcode()相等时,equals()方法也可能不等,所以必须用第2条准则进行限制,才能保证加入的为非重复元素。

),重点是equals,重写hashCode只是技术要求(为了提高效率)
2),为什么要重写equals呢,因为在java的集合框架中,是通过equals来判断两个对象是否相等的
3),在hibernate中,经常使用set集合来保存相关对象,而set集合是不允许重复的。我们再来谈谈前面提到在向hashset集合中添加元素时,怎样判断对象是否相同的准则,前面说了两条,其实只要重写equals()这一条也可以。
但当hashset中元素比较多时,或者是重写的equals()方法比较复杂时,我们只用equals()方法进行比较判断,效率也会非常低,所以引入了hashcode()这个方法,只是为了提高效率,但是我觉得这是非常有必要的(所以我们在前面以两条准则来进行hashset的元素是否重复的判断)。

 

 

 

 

转自:https://blog.csdn.net/wufeifan_learner/article/details/89640176

    https://blog.csdn.net/xl_1803/article/details/80445481?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

posted @ 2020-03-23 14:33  why666  阅读(124)  评论(0)    收藏  举报