最近,在网上浏览了关于equals(),hashCode()的文章,强调当一个对象被当作键值(或索引)来使用的时候要重写这两个方法,但我试了一下列子:
import java.util.HashMap;
public class Person {
private String id;
public String getId(){
return id;}
public void setId(String id){
this.id=id;
}
public static void main(String args[]){
Person p=new Person();
Person pp=new Person();
HashMap map=new HashMap();
map.put(p,"p1");
map.put(pp,"p2");
System.out.print(map.get(p));
}
}
即使没有重写也能得到正确的值p2,为什么
import java.util.HashMap;
public class Person {
private String id;
public String getId(){
return id;}
public void setId(String id){
this.id=id;
}
public static void main(String args[]){
Person p=new Person();
Person pp=new Person();
HashMap map=new HashMap();
map.put(p,"p1");
map.put(pp,"p2");
System.out.print(map.get(p));
}
}
即使没有重写也能得到正确的值p2,为什么
两个对象之间要互相equals的话,就必有具备相同的hashcode.
业务上来讲应该得到p1,你得到p2,还正确??
private String id; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public static void main(String args[]) {
Person p = new Person();
p.id = "123";
Person pp = new Person();
pp.id = "321";
HashMap map = new HashMap();
map.put(p, "p1");
map.put(pp, "p2");
Person pNew = new Person();
pNew.id = "123";
System.out.print(map.get(pNew));
}
}最后一句中,本来我应该认为 id 相同,应该可以取出"p1"这个值,但是Map是不知道 pNew 是等同于 p的,所以会返回null
put和get的时候的hashCode()相等(p.hashCode() == p.hashCode()),
值相等(p.equals(p)),
所以能取到.
但是像我的代码中,另外创建一个Person对象,虽然我认为应该是相同的Person,但是由于它与Map中的Key具有不相同的HashCode也不equals,所以是取不出来
虽然 a 与 b不是同一个对象(即 a != b),但是你希望无论使用 a 还是 b 都可以从map中取出相同的 value,或者在 set 中不会重复出现也就是你会认为 a 与 b 的内容是相同的
equeals和hashCode方法有必然联系吗?
比如:你向 Set 集合中添加一个一个Person 对象 如果 这个Person 对象的
name 相同就认为是同一个对象的话。那么你就必须同时重写 hashCode,和equals 方法。
Set 集合是不可以包含重复元素的
Person p1 = new Person("abc");
Person p2 = new Person("abc");
p1 ,p2 加到Set 集合中 会是两个对象。
但事实上是 同一个人。
这时就必须重写。
----
在Java的规范中规定了有必然的联系, 即 如果 a.equals(b),那么必定有 a.hashCode() == b.hashCode(),反之【不一定成立】如果不满足这个条件则map, set等的处理会出现错误的
这是一个规范
是因为对象的继承的Object.hashcode()方法返回的值肯定可以唯一确定这个对象
重写的原因就是为了改变这个效果(或者其他理由)
如果a==b,则a.equals(b),a.hashCode = b.hashCode.