只有类的实例对象要被采用哈希算法进行存储和检索时,这个类才需要按要求覆盖hashCode方法。即使程序可能暂时不会用到当前类的hashCode方法,但是为他提供一个hashCode方法也不会有什么不好,没准以后什么时候有用到这个方法了,所以,通常要求hashCode方法和equals方法一并被同时覆盖。
//HashSet比较时hashCode方法和equals方法都用了
HashSet:采用哈希算法的集合。实现了Collection接口,只能存入不同HashCode对象,即只存入不同的对象,如果希望存入具有相同内容的两个对象,则需覆盖对象的HashCode和 equals方法。
提示
(1)通常情况,自己编程时要做到:一个类的两个实例对象用equals方法比较的结果相等时,他们的哈希吗也必须相等,但反之则不成立,即equals方法比较的结果不相等的对象可以有相等的哈希吗或者说哈希吗相等的两个对象的equals方法的比较的结果可以不相等。因为默认的equals方法比较的是hashcoad值。例如,字符串”BB”和”Aa”的hashCode的结果相等,但equals的结果不相等。
(2)当一个对象被存储进HashSet集合中以后,就不能修改这个歌对象中的那些参与计算哈希值的字段,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前的引用作为参数区HsahSet集合中检索对象,也将返回找不到对象的结果,这也是导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。
例子:
package cn.zyj26.review;
public class ReflectPoint {
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
package cn.zyj26.review;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class ReflectTest2 {
public static void main(String[] args) throws Exception{
Collection<ReflectPoint> collections=new ArrayList<ReflectPoint>();
ReflectPoint pt1 = new ReflectPoint(1,1);
ReflectPoint pt2 = new ReflectPoint(2,2);
ReflectPoint pt3 = new ReflectPoint(1,1);//默认的equals方法比较的是hashcoad值,所以pt3与pt1不相等,要相等必须重写equals方法
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
System.out.println(collections.size());//4
Collection<ReflectPoint> collectionsH=new HashSet<ReflectPoint>();
collectionsH.add(pt1);
collectionsH.add(pt2);
collectionsH.add(pt3);
collectionsH.add(pt1);//3,重写equals可以得到结果2
System.out.println(collectionsH.contains(pt1));//true
pt1.y=22;//导致哈希值改变了!!这样也无法删除了,即collectionsH.remove(pt1);无效了
System.out.println(collectionsH.contains(pt1));//false
System.out.println(collectionsH.size());
}
}
Ps:
解释equals(),hashcode()和== http://justsee.iteye.com/blog/1317565