/**
* hashmap的key有没有存放自定义对象。
* 存放了,那么必然要重写equals方法,也就必然重写hashcode方法
*
* 这也就是为什么String要进行重写equals和hashcode?
* 并且String设计为final?
* 因为String做为key比较的是内容,那么当你修改后,必然会导致key不同,也就会出现同一个对象但却得不到Value
*/
public class EqualsHashcode {
private String name;
private String id;
public EqualsHashcode(String name, String id) {
this.name = name;
this.id = id;
}
@Override
public boolean equals(Object obj) {
//默认比较的是地址
if (obj == null) return false;
if (this == obj) return true;
if (obj instanceof EqualsHashcode){
return this.id.equals(((EqualsHashcode)obj).id);
}
return false;
}
//为什么重写equals要重写hashcode
//如何重写hashcode,我们可以直接返回equals比较的内容,或者为了散列性,我们可以定义一个散列函数。
@Override
public int hashCode() {
//简单起来,我们直接返回Id
return Integer.parseInt(id);
}
public static void main(String[] args) {
EqualsHashcode equalsHashcode1 = new EqualsHashcode("mao","123");
EqualsHashcode equalsHashcode2 = new EqualsHashcode("wu","123");
System.out.println(equalsHashcode1.equals(equalsHashcode2));
}
}
为什么重写equals需重写hashcode?
一般我们重写一个对象的equals方法,如果不用在需要使用hashcode的集合中,那么我们是没必要重写hashcode的。
使用场景:比如以自定义对象做key,存在HashMap中:
java集合中如HashMap,通过hashcode求出在在数组中的下标,当存在冲突我们就用链表的形式。
所以 当hashcode相同,根据equals来判断是否同一个对象。反过来,当equals相同,则可以推出来hashcode相同,所以重写equals方法要重写hashcode。(另一方面,相同的对象是不能散列在数组中不同位置的,就没办法覆盖了,所以equals相等时hashcode必须要相同)
String设计为final?
因为String做为key,当你修改value后,必然会导致key不同,进而会导致hashcode不同(String源码根据value来求hashcode),那么在通过这个String对象获取value时却获取不到了或者获取错了