目录
hashCode(),equals()两种方法的关系
在java中,每个对象都可以通过调用自己的hashCode方法来得到自己的哈希值,相当于自己的身份信息,但是在java中不同的对象可能会拥有相同的哈希值,不过还是可以用这个哈希值来提前做一些判断:
1.如果两个对象的哈希值不同,那么这两个对象肯定是两个不同的对象。
2.如果两个对象相同,他们的哈希值一定相等。
3.哈希值相等的两个对象,不一定相等。
java的容器类被分为Collection 和 Map 两大类。而Collection又被进一步分为List和set,其中map和set都不允许元素重复,因此每次插入数据时都需要去比较。
一想到比较,可能很多人就想到了我们可以使用equals去比较,但是当容器中的元素很多时,每次插入新元素都一个个去调用equals方法就比较,时间复杂度O(n)那效率可想而知。
但是使用哈希值的话,每次比较的时间复杂度就是O(1)。
因此,在这些集合的实现中,首先先调用hashCode()方法 先进行哈希对比,如果不相同,则没有重复元素,如果相同,在调用equals方法进行比较。
关于java的容器类不太清楚的可以去看我的这篇博客:
为什么重写equlas,就要重写hashCode方法
在下面的代码中,我们实现了一个类Cat,重写了equals方法,只要属性name和age相同,两个对象就相等。但是没有重写hashCode方法
public class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return age == cat.age && name.equals(cat.name);
}
public static void main(String[] args) {
Cat cat1=new Cat("mimi",3);
Cat cat2=new Cat("mimi",3);
System.out.println(cat1.equals(cat2));
System.out.println(cat1.hashCode());
System.out.println(cat2.hashCode());
}
}
结果显示通过equals比较两个对象是相等的,但是两个对象的hashCode值又不同。通过上面两者的关系,当我们重写了equals而不重写hashCode时, 违背了规定 相等(相同)的对象必须具有相等的哈希码(或者散列码)。同时会让容器类中的set和map失效,会让容器中出现相同的值,违背了这些容器的设计理念。