本文很多都参考了别的大神的文章,这是我第一次写博客。引用的文章在更多文章那里可以找到,感谢他提供的博文,同时做出道歉
最近,学到java集合框架时,接触到了两个让我傻傻分不清楚的两个方法:hashcode()和 equals()。在set 和 map中,往里面添加自定义类时,自定义的类都要重写了hashcode()和 equals(),到底为什么呢?
equals(Object obj)和hashcode()这两个方法是在Object类中定义的,所以每一个类都有这两个方法。
equals(Object obj)方法用来判断两个对象是否相同,如果相同则返回true,否则返回false。 实现代码如下:
<span style="font-size:18px;">public boolean equals(Object obj) {这个方法是对两个对象的地址值进行的比较(即比较引用是否相同),但是,String 、Math、还有Integer、Double。。。。等这些封装类已经覆盖了父类的equals()方法,它们是对类内容的比较而不是地址的比较了。例如下面的String的内部方法:
return (this == obj);
} </span>
<span style="font-size:18px;">public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
</span>
Java语言对equals()的要求如下,这些要求是必须遵循的:
• 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
• 反射性:x.equals(x)必须返回是“true”。
• 类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
• 还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
• 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。
hashcode()方法的官方解析为:
|
所以,equals()方法主要是用来判断对象是否相等的,而哈希码(hashcode)主要是用来查找的,根据百科,hashcode是它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。
在实际的程序编写中,要考虑四个问题:
第一:当哈希码相同,而equals()返回值为false
第二:当哈希码相同,而equals()返回值为true
第三:当哈希码不同,而equals()返回值为false
第四:当哈希码不同,而equals()返回值为true
分别代表什么?
当我们将某个对象存到set中时,如果该对象的属性参与了hashcode的计算,那么以后就不能修改该对象参与hashcode计算的那些属性了,否则会引起意向不到的错误的。正如测试中,不能够移除stu1对象。
总结:
1、equals方法用于比较对象的内容是否相等(覆盖以后)
2、hashcode方法只有在集合中用到
3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
4、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。
5、将元素放入集合的流程图: