目录
==
对于基本数据类型
来说,==比较的是值
对于引用数据类型
来说,==比较的是对象的内存地址
equals()
类未重写equals()
方法 :等价于通过==
去比较这两个对象
类重写了equals()
方法 :通常的做法是若两个对象的内容相等
则返回true;否则返回fasle
为什么类没有重写equals()方法:等价于通过==去比较这两个对象?
因为Object是所有类的父类、如果没有一个类没有重写equals()方法就会使用Object的equals()方法、原码如下
public boolean equals(Object obj) {
return (this == obj);
}
==
和 equals()
区别
== 的作用:主要判断两个对象是否为同一个对象
equals()的作用:主要判断两个对象内容是否相等
java对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(null),永远返回是"false";x.equals(和x不同类型的对象)永远返回是"false";
hashCode()介绍
hashCode()
是Object
的方法,所以Java中的任何类有 hashCode()
函数。
hashCode()
的作用 是获取哈希码
/散列码
。
哈希码/散列码是一个int整数,他的作用 是确定该对象在哈希表
中的索引
的位置
哈希表存储的是键值对 (key-value);
原理是:散列表的本质是通过数组
实现的,计算key
得到的哈希码
确定了value
在数组中的索引的位置,所以知道了 key 就可以取出来 value;
所以它的特点是: 能根据key
快速的检索出对应的value
;
hashCode() 和 equals() 的关系
类不会被哈希表收集时
不会在 HashSet
, Hashtable
, HashMap
等本质是哈希表
的数据结构中用到该类。
例如,不会创建该类的 HashSet
集合。
在这种情况下,该类的 hashCode()
和 equals()
没有半毛钱关系的!
原因是:由哈希码来确定对象在散列表中的位置,不创建散列表也不需要哈希吗,自然就用不上 hashCode()
这种情况下,可以用 equals()
来比较两个对象值是否相等。而 hashCode()
则根本没有任何作用,所以,不用理会 hashCode()
类会被哈希表收集时
我们会在 HashSet
, Hashtable
, HashMap
等等这些本质是哈希表
的数据结构中用到该类。
例如,会创建该类的 HashSet
集合。
在这种情况下,该类的 hashCode()
和 equals()
是有关系的。
如果两个对象 hashCode()
值相等,它们并不一定相等,有可能是哈希冲突。
如果两个对象 hashCode()
值相同,且 equals()
比较返回true,则这两个对象相等
HashSet中已经有1000个元素。当插入第1001个元素时,需要怎么处理?
(1) 将第1001个元素逐个的和前面1000个元素进行比较 效率低下!!
(2)当把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值,如果没有相同的hashcode,HashSet会视为对象没有重复出现。 如果发现有相同 hashcode 值的对象,这时会调用equals()方法来检查内容是否相同。如果相同,HashSet 不会让其加入。如果不同的话,就会重新散列到其他位置。 这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
String的hashCode()计算方法
"abc"
h = h * 31 + 97-- - (0 * 31 + 97)
h = h * 31 + 98-- - (0 * 31 + 97) * 31 + 98
h = h * 31 + 99-- - ((0 * 31 + 97) * 31 + 98) * 31 + 99
参考
==和 equals 的区别
Java hashCode() 和 equals()的若干问题解答
equals、Objects.equals、Objects.deepEquals区别和联系