一、equals()
equals()方法用于比较两个对象是否相等
equals在object中的定义:
public boolean equals(Object ojb){return (this == ojb)
}
很明显对比的是像个对象的地址(即引用)是否相等
String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法,进行内容的比较。
当然,基本类型是进行值的比较。
性质:
- 自反性:
x.equals(x)
一定是true
- 对称性:
x.equals(y)
是true
时,y.equals(x)
也是true
- 传递性:如果
x.equals(y)
是true
,同时y.equals(z)
是true
,那么x.equals(z)
一定是true
- 一致性:如果用于equals比较的对象信息没有被修改的话,多次调用时
x.equals(y)
要么一致地返回true
要么一致地返回false
- 对于任意不为
null
的引用值x
,x.equals(null)
返回false
需要注意的是当equals()
方法被override时,hashCode()
也要被override。按照一般hashCode()
方法的实现来说,相等的对象,它们的hash code一定相等。
二、hashCode()
对象调用hashCode()方法会返回一个hash Code值,相同的对象,返回相同的hash Code值,该方法被用于hashTables,例如HashMap。
性质:
- 如果一个对象传递给equals作比较的信息没有被修改的话,多次调用hashCode()方法,返回的值始终唯一
- 两个对象调用object.equals(obj)相等,那么这两个对象的hashCode()一定相等
- 两个对象调用object.equals(obj)不相等,那么这两个对象的hashCode()不一定不相等(也就是说hashCode()相等,equals()不一定相等)
Java对象的eqauls方法和hashCode方法是这样规定的:
1、相等(相同)的对象必须具有相等的哈希码(或者散列码)。
2、如果两个对象的hashCode相同,它们并不一定相同。
三、Hashset、Hashmap、Hashtable与hashcode()和equals()的密切关系
Hashset是继承Set接口,Set接口又实现Collection接口,这是层次关系。
那么Hashset、Hashmap、Hashtable中的存储操作是根据什么原理来存取对象的呢?
以HashSet为例进行分析,我们都知道:在hashset中不允许出现重复对象,元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢?
在java的集合中,判断两个对象是否相等的规则是:
1.判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入2
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。)
2.判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)
为什么是两条准则,难道用第一条不行吗?不行,因为前面已经说了,hashcode()相等时,equals()方法也可能不等,所以必须用第2条准则进行限制,才能保证加入的为非重复元素。