equals方法和hasCode方法,为什么重写equals()的时候要重写hasCode()?
equals()和hashCode()在面试的时候被问到的频率很高,equals()方法和hasCode()方法有什么关系?为什么重写equals()的时候要重写hasCode()?
equals和hasCode是Object类中的两个方法,Object类是所有类的父类
新建一个带有姓名和年龄的Person类
public class Person {
private Integer age;
private String name;
public Person(Integer age, String name) {
this.age = age;
this.name = name;
}
}
实例化并调用equals方法进行比较
public static void main(String[] args) {
Person person = new Person(11,"张三");
Person person2 = new Person(11,"张三");
System.out.println(person.equals(person2)); // 输出结果为false
}
这是实际调用了Object类中的equals方法,它是用 " == " 进行判断的," == " 是判断两个对象的地址值是否相同,如果地址值相同,就认为是同一个对象。
所以equals方法是判断两个对象是否相同。
Object类中的equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
但是我们在项目开发中,一般如果两个对象的属性相同,我们就认为他们是相等的,所以我们会重写equals方法,只判断他们的属性值是否相同,就是说只要年龄和姓名相等,我们就认为是同一个人。
重写后的equals方法:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EqualsPerson)) return false;
EqualsPerson that = (EqualsPerson) o;
return age.equals(that.age) &&
name.equals(that.name);
}
进行重写后,再次调用equals方法进行比较
public static void main(String[] args) {
// 重写equals()之后
EqualsPerson equalsPerson = new EqualsPerson(11,"张三");
EqualsPerson equalsPerson1 = new EqualsPerson(11,"张三");
System.out.println(equalsPerson.equals(equalsPerson1)); // 输出结果为true
}
那我们重写equals()之后的结果都为true了,为什么还要重写hashCode()?
因为在项目中如果两个对象相等我们一般会就行去重操作,把两个对象放一个set里
public static void main(String[] args) {
Person person = new Person(11, "张三");
Person person2 = new Person(11, "张三");
Set<Person> personSet = new HashSet<>();
personSet.add(person);
personSet.add(person2);
System.out.println(person.equals(person2)); //输出结果为true
for (Person personItem : personSet) {
//输出结果为: Person{age=11, name='张三'}Person{age=11, name='张三'}
System.out.print(personItem.toString());
}
}
看输出结果set中还是两个对象,去重失败了。
年轻人不能头太铁,要不我们试试也重写一下hashCode()呢?
hashCode() 的作用:
主要是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
没有重写之前,我们看一下hashCode()的返回值
public static void main(String[] args) {
Person person = new Person(11, "张三");
Person person2 = new Person(11, "张三");
System.out.println(person.hashCode()); // 输出结果为356573597
System.out.println(person2.hashCode()); // 输出结果为1735600054
}
object类中的 hashCode()方法
public native int hashCode();
我们可以看到hashCode()的返回值是不一样的,
重写hashCode方法:
@Override
public int hashCode() {
return Objects.hash(age, name);
}
我们看一下重写之后,hashCode()的返回值
public static void main(String[] args) {
Person person = new Person(11, "张三");
Person person2 = new Person(11, "张三");
System.out.println(person.hashCode()); // 输出结果为776191
System.out.println(person2.hashCode()); // 输出结果为776191
}
我们在把两个对象放入set去重
public static void main(String[] args) {
Person person = new Person(11, "张三");
Person person2 = new Person(11, "张三");
Set<Person> personSet = new HashSet<>();
personSet.add(person);
personSet.add(person2);
System.out.println(person.equals(person2)); //输出结果为true
for (Person personItem : personSet) {
//输出结果为: Person{age=11, name='张三'}
System.out.print(personItem.toString());
}
}
查看输出结果,去重成功,可以看出set去重时候会进行hash,hash相同的时候才可以去重
总结:
1.equals和hasCode是Object类中的两个方法,因为在Object类中的equals方法是用"=="进行判断,即地址值是否相同, 在业务开发中,如果两个对象的值相等,我们一般就认为他们是同一对象,所以我们都会重写equals方法。hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数,这个哈希码的是用来确认该对象在哈希表中的索引位置。
2.hashCode() 在散列表中才有用,就是说我们会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,用到该类的时候,才需要重写hashCode()方法,比如说创建该类HashSet集合,set是根据hash进行去重的
3.如果两个对象相等,那么它们的hashCode()值一定相同,但是如果两个对象hashCode()相等,一定相等吗?
答:不一定,因为两个不同的键值对,哈希值相等,可能是发生了哈希冲突。
欢迎在评论区留言交流,喜欢的小伙伴记得点赞。感谢阅读!
推荐阅读
-
荐 java父类-Object类-equals与==-方法的重载和重写-游离块-this关键字
-
java中重写equals()方法的时候为什么要重写hashCode()方法?
-
哈希表中为什么要重写hashCode与equals方法
-
Java中为什么要重写hashCode方法和equals方法?
-
重写equals方法为什么要重写hashCode方法
-
Java:object类 中常用equals()和 toString()方法的重写
-
java实体类中equals和hashCode方法的重写
-
java中“==”和equals()的区别、hashCode()、为什么重写equals()方法必须重写hashCode()
-
为什么equals()方法要重写?
-
哈希表中为什么要重写hashCode与equals方法