一、equals方法:
1.1、"=="和equals()方法的区别和联系
了解equals重写之前当然要先了解一下equals与==的区别啦,为什么有了==还要有equals以及其重写呢?
"=="比较基本数据类型时比较的是表面值内容,而比较两个对象时比较的是两个对象的内存地址值
对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
1.2、对比==与equals
先阅读一下代码(真的要看嘛>_<):
package com.equal;
/**
* @program: st
* @ClassName Test
* @description:
* @author: 苏芮溪
* @create: 2024−10-22 19:13
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println("----------");
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
}
}
猜一猜这个的输出结果会是什么呢?是不是都是true呢?
欸?这不是输出结果也不一样吗?
为什么会这样呢? 这是因为在String类中,equals方法是被重写过后的
1.3、重写equals方法:
当类中没有重写时,例如我们自定义的Person类中:
package com.equal;
/**
* @program: st
* @ClassName Person
* @description:
* @author: 苏芮溪
* @create: 2024−10-22 19:14
* @Version 1.0
**/
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.equal;
/**
* @program: st
* @ClassName Test
* @description:
* @author: 苏芮溪
* @create: 2024−10-22 19:13
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
Person person1 = new Person("Tom",19);
Person person2 = new Person("Tom",19);
System.out.println(person1 == person2);
System.out.println(person1.equals(person2));
}
}
很显然,输出的结果无论是用的==比较还是用的equals比较都是false;但是这是同一个人,那就需要重写equals方法了;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
在Person类中加入以上代码,就可以实现根据姓名和年龄判断是否是同一个人。
加入equals重写后再次运行:
二、hashcode方法:
在重写equals()后,一定要重写hashCode()方法
2.1、注意事项:
在重写equals()后,一定要重写hashCode()方法
如果两个对象的equals相等,那么它的hashCode相等
两个对象的equals不相等,那么它的hashCode不要求它不相等,但是一般情况下不相等
hashCode相等不代表两个对象相等!!!
2.2、深入了解一下< HashCode >:
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
常见的散列表实现方式:用数组作为哈希函数的输出域,输入值经过哈希函数计算后得到哈希值。然后根据哈希值,在数组种找到对应的存储单元。当发生冲突时,对应的存储单元以链表的形式保存冲突的数据(链地址法)。
那么像上述的例子,元素 5 与 元素 40 都是存储在 hsahcode = 5 的位置后面,(5mod7 == 40 mod 7 == 5),此时元素 5与元素 40的hashcode就是一样的(都是5);
同理,16与2也是一样的;
所以说:hashCode相等不代表两个对象相等!!!
2.3、hashcode方法重写
package com.equal;
import java.util.Objects;
/**
* @program: st
* @ClassName Person
* @description:
* @author: 苏芮溪
* @create: 2024−10-22 19:14
* @Version 1.0
**/
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.equal;
/**
* @program: st
* @ClassName Test
* @description:
* @author: 苏芮溪
* @create: 2024−10-22 19:13
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
Person person1 = new Person("Tom",19);
Person person2 = new Person("Tom",19);
Person person3 = new Person("Tom",15);
System.out.println(person1.equals(person2));
System.out.println(person1.hashCode() +" "+ person2.hashCode());
System.out.println(person1.equals(person3));
System.out.println(person1.hashCode() +" "+ person3.hashCode());
}
}
经过哈希表达式计算后的hashcode相等的实在不好找,就不敲代码测试了,欸嘿~