说说hashCode和equals的相关问题

原文链接:https://blog.csdn.net/CSDN_Ty/article/details/98877883

本文的内容主要想解决一下几个问题:

  • equals() 和 == 的作用是什么?
  • equals() 和 == 的区别是什么?
  • hashCode()的作用是什么?
  • hashCode()与equals()之间有什么联系?

equals() 和 == 的作用

  • == 是用来判断两个对象是否为同一个对象,通过判断两个对象的内存地址来区分它们是否相等。
  • equals() 是用来判断两个对象是否相等,equals()定义在Object类中,所有类都继承了该方法。

从源码可以看出,默认情况下,equals与==没有区别,equals就是调用的==来进行判断。

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}

所以,通常我们都会重写equals方法:两对象内容相等,则返回true,否则返回false。举例:

①没有重写equals()方法时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test {

@AllArgsConstructor
@Setter
@Getter
public static class Student {
private String name;
private int age;
}

public static void main(String[] args) {
Student stu1 = new Student("ye17186", 18);
Student stu2 = new Student("ye17186", 18);
System.out.println("stu1.equals(stu2): " + stu1.equals(stu2));
}
}

输出结果:

解析:

由于stu1、stu2都是直接new出来的对象,它们指向两块不同的内存地址,在未重写equals方法的情况下,调用equals()方法其实就是调用==,比较的是他们的内存地址是否相同,所以这里打印的结果的false。

②重写equals()方法时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test {

@AllArgsConstructor
@Setter
@Getter
public static class Student {
private String name;
private int age;

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return name.equals(student.getName()) && age == student.age;
}
}

public static void main(String[] args) {
Student stu1 = new Student("ye17186", 18);
Student stu2 = new Student("ye17186", 18);
System.out.println("stu1.equals(stu2): " + stu1.equals(stu2));
}
}

输出结果:

解析:

重写equals方法后,就会使用equals方法内的逻辑来判断是否相等,例子中直接比较了name和age是否相等,stu1和stu2两个对象,他们的name都是ye17186,age都是18,所以这里输出的结果是true。

equals()与==的区别

上面已经解析过了,从设计上说==是用来判断是否为同一个对象,equals()用来判断两个对象是否相等。如果我们没有重写equals()方法,那么二者其实是等价的。但一般我们会重写equals()方法,这样会按照我们重写的逻辑来判断两个对象是否相等。

hashCode的作用

  • hashCode()的作用是获取哈希码,也成为了散列码,它实际上返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
  • hashCode()定义在java.lang.Object中,这意味着JAVA中任何类都有这个函数。
  • 虽然每个JAVA类都有hashCode函数,但是仅仅当创建某个“类的散列表”时,该类的hashCode()才有用(作用是确定该类的每一个对象在散列表中的位置),其他情况下(例如:创建类的单个对象,或者创建类的对象数组等),类的hashCode()没有作用。
  • 上面的散列表,指的是JAVA集合中本质是散列表的类,如HashMap、HashTable、HashSet。
  • 也就是说,hashCode()在散列表中有用,在其他情况下没用。在散列表中hashCode()用于获取对象的散列码,从而确定该对象在散列表中的位置。
  • 如果两个对象相等,他们的散列码一定相等;但是如果散列码相等,它们不一定相等

hashCode()与equals之间的联系

在非”本质是散列表的类”中,两者没有任何关系。而在”本质是散列表的类”中,在HashSet中,如果两个对象的hashCode相同,即使equals不等,它们在集合中也只会存储一个。

评论