==和equals的区别
==:对于基本数据类型来说,==就是来判断值是不是相等,对于引用类型来说,就是判断用来判断两个对象的地址是不是相等,也就是用来判断是不是同一个对象。
equals():equals()只能用于比较引用数据类型,可以将equals()分“两种”。
一种是没有重写的来自Object类的equals(),因为Object类是根类,每个类都会有这个方法,如果没有重写,那么equals()就是比较的对象是否相等,可以视作与==相同。
第二种是重写了的equals(),通常会覆盖原有equals(),使得对象值相等时就相等。这时的equals()就是用来比较对象值是否相等了。
那么说到重写equals(),我们会发现在idea这样的IDE中重写类的equals方法时会绑定一个hashCode()方法一起重写,那么他们之间有什么关系吗?
hashCode() 和 equals() 的关系
和equals方法一样,hashCode()在Object中就定义了,因此每个java类都有该方法。hashCode()方法的目的时生成一个哈希码,就是一个数值,这个哈希码用于确定对象在散列表(例如hashSet,HashMap等)中的位置,也就是将对象加入散列表时要根据该哈希值判断其插入的位置。
所以,即使每个java类都有该hashCode()函数,如果你不需要创建该类的散列表,那么hashCode()就没有用~,这种情况下equals()和hashCode()也就没有半毛钱关系了。你可以只重写equals()方法不重写hashCode方法。
But,当你要创建某个类的散列表时,equals()和hashCode()就有关系了。
首先,因为你要创建某个类的散列表,而散列表的存取依赖于散列码也就是哈希码,那么你就需要用到hashCode(),以hashSet为例,要往hashSet添加对象,那么我们先根据hashCode()计算出来的哈希码查找其插入位置。
如果此时我们没有重写hashCode(),只重写了equals()函数,就会出现相同的对象其hashCode值不同,那么在插入hashSet的过程中,就会根据两个不同的地址分别插入,这会使得hashSet中插入两个值相同的对象,出现与预期不符的结果。
当我们重写hashCode()后,根据hashCode()的结果寻找插入位置,如果该位置为空,那么就直接插入,如果不为空,那么就需要判断该位置的对象和我要插入的对象是不是相同,如果相同就得放弃插入了,因为Set集合不能有重复对象。那么如何判断对象是不是相同呢,那么就应该依据重写后的equals()方法,如果这两个对象值相等,说明是两个相等对象,拒绝插入;如果对象值不相等,那就是不同的对象出现了散列值相同的对象,也就是出现了哈希冲突,可以用再散列的方法解决冲突,即另外找个位置插入。
可以发现,上面插入hashSet的过程中如果在出现哈希码重复时需要equals()方法帮助判断是不是相同的对象。
重写hashCode()的目的是为了保证相同的对象其hashCode值一定相同。
注:不同的对象hashCode值也可能会相同。
参考文章:https://www.cnblogs.com/skywang12345/p/3324958.html
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(getName(), user.getName()) &&
Objects.equals(getAge(), user.getAge());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
}