为什么重写equals方法一定要重写hashcode方法
先来看看如果重写类的equals方法,但是没有重写hashcode方法会发生什么。
例如:
重写了一个类HashTest的equals方法,但是没有重写HashTest的hashCode方法,它的两个对象A和B逻辑上比较是正确的。
在插入操作中
将A和B作为key放入HashMap中(一般放在key的是String),先调用A和B的hashcode方法来确定存放在那里。
因为没有重写hashcode方法,自动调用原生的Object的hashcode,这样就使得A和B产生不同的hashcode,从而放在了不同的位置。而实际上A和B应该是放在同一位置。
在查找操作中
A已作为key放入HashMap中,通过B作为key来查找A中的值,查找时,先比较hashcode是否相等,如果相等,再比较对象是否相等。
但是这里,因为没有重写hashcode方法,自动调用原生的Object的hashcode,这样就使得A和B产生不同的hashcode,从而不会进行下一步的equals比较,通过B就找不到A。
查找示例代码如下:
import java.util.HashMap;
public class HashTest
{
private String s;
private int x;
public String getS()
{
return s;
}
public void setS(String s)
{
this.s = s;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public boolean equals(Object obj)
{
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
HashTest h = (HashTest) obj;
if (h.s.equals(this.s) && h.x == this.x)
return true;
else
return false;
}
public static void main(String[] args)
{
String s = "1";
HashTest A = new HashTest();
A.setS(s);
A.setX(1);
HashTest B = new HashTest();
B.setS(s);
B.setX(1);
HashMap<HashTest, String> map = new HashMap<HashTest, String>();
map.put(A, "插入");
//System.out.println(A.equals(B));
//System.out.println(A.hashCode());
//System.out.println(B.hashCode());
//System.out.println(map.get(A));
System.out.println(map.get(B));
}
}
结果如下:
重写hashcode:
package test;
import java.util.HashMap;
public class HashTest
{
private String s;
private int x;
public String getS()
{
return s;
}
public void setS(String s)
{
this.s = s;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public boolean equals(Object obj)//注意不可以更改方法名,以及方法的参数
{
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
HashTest h = (HashTest) obj;
if (h.s.equals(this.s) && h.x == this.x)
return true;
else
return false;
}
public int hashCode()//注意不可以更改方法名,这里的“c”要大写,以及方法的参数,
{
int hash = 7;
hash = 31 * hash + x;
hash = 31 * hash + s.hashCode();
return hash;
}
public static void main(String[] args)
{
String s = "1";
HashTest A = new HashTest();
A.setS(s);
A.setX(1);
HashTest B = new HashTest();
B.setS(s);
B.setX(1);
HashMap<HashTest, String> map = new HashMap<HashTest, String>();
map.put(A, "插入");
//System.out.println(A.equals(B));
//System.out.println(A.hashCode());
//System.out.println(B.hashCode());
//System.out.println(map.get(A));
System.out.println(map.get(B));
}
}