equals方法与hashcode方法的重写

一、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相等的实在不好找,就不敲代码测试了,欸嘿~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值