本文参考自两篇文章,各取其长,整理这篇文章。
文章来源:https://blog.csdn.net/tuolaji8/article/details/48417031
equals()方法在Object类中的定义:
public boolean equals(Object obj){
return (this == obj);
}
equals()的定义为:
public native int hashCode();
是一个本地方法,返回的对象的地址值。
1.hashcode()和equals()是在哪里被用到的?什么用的?
HashMap是基于散列函数,在jdk1.7中以数组和链表的方式实现、在jdk1.8中以数组+链表+红黑树的形式实现。而对于每一个对象,通过其hashCode()方法可为其生成一个整形值(散列码),该整型值被处理后,将会作为数组(Map.Entry[])下标,存放该对象所对应的Entry(存放该对象及其对应值)。
equals()方法则是在HashMap中插入值或查询时会使用到。当HashMap中插入 值或查询值对应的散列码与数组中的散列码相等时,则会通过equals方法比较key值是否相等,所以想以自建对象作为HashMap的key,必须重写 该对象继承object的equals方法。
2.本来不就有hashcode()和equals()了么?干嘛要重写,直接用原来的不行么?
HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地 址,这样即便有相同含义的两个对象,比较也是不相等的,例如,
Student st1 = new Student("wei","man");
Student st2 = new Student("wei","man");
正常理解这两个对象再存入到hashMap中应该是相等的,但如果你不重写 hashcode()方法的话,比较是其地址,不相等!
如果对上面的例子不能理解的话,就参考如下代码,照理来说str2中的内容会覆盖掉str1的内容,而上面的例子没有重写hashCode()和equals()方法是不行的,String中有重写equals()和hashCode()方法了。:
Map map = new HashMap<>() ;
String str1 = "demo" ;
String str2 = "demo" ;
map.put(str1,"hello") ;
map.put(str2,"hello") ;
HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等 的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为 同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等。
接下来是另一篇博客的一个例子,供大家学习参考
文章来源:https://blog.csdn.net/qq_35489960/article/details/78926547
自定义 PhoneNumber类
package comjk;
public class PhoneNumber {
private int prefix; //区号
private int phoneNumber; //电话号
public int getPrefix() {
return prefix;
}
public void setPrefix(int prefix) {
this.prefix = prefix;
}
public int getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(int phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
//main 方法
public static void main(String[] args) {
Map map =new HashMap();
PhoneNumber phoneNumber1=new PhoneNumber();
phoneNumber1.setPhoneNumber(111);
phoneNumber1.setPrefix(111);
PhoneNumber phoneNumber2=new PhoneNumber();
phoneNumber2.setPhoneNumber(222);
phoneNumber2.setPrefix(222);
map.put(phoneNumber1, "111");
map.put(phoneNumber2, "222");
System.out.println(map.get(phoneNumber1));
System.out.println(map.get(phoneNumber2));
PhoneNumber phoneNumber3=new PhoneNumber();
//参数内容和phoneNumber2一样
phoneNumber3.setPhoneNumber(222);
phoneNumber3.setPrefix(222);
System.out.println(map.get(phoneNumber3));
}
输出结果
111
222
null //因为没有重写hashCode和equals方法,所以取不出phoneNumber2的值,因为这里phonenumber2和phonenumber3地址不同。
//在PhoneNumber 类中重写equals()和hashCode()方法;
@Override
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof PhoneNumber))
{
return false;
}
PhoneNumber pn = (PhoneNumber)o;
return pn.prefix == prefix && pn.phoneNumber == phoneNumber;
}
@Override
public int hashCode()
{
int result = 17;
result = 31 * result + prefix;
result = 31 * result + phoneNumber;
return result;
}
输出结果
111
222
222