正确重写hashcode hashcode与equals方法 集合元素如何判断是否相等 集合如何查看是否包含某个元素

时间:2022-09-03 00:26:51

首先记住两句话

相等的两个对象,即equals(Object)方法判断两个对象相等,那么他们必须要有相同的hashcode

hashcode相同的两个对象,他们可能相同,也可能不相同

简单地说可以这么理解,hashcode是java实现中经常用到的比如在HashMap HashSet,根据hashcode不等就可以断定两个对象不等,如果相等再去比较equals,大大减少了equals的调用次数,效率就高很多了

原理搜一下有很多文章,不再多说

重点说一下应用,大家或许看到很多地方说:

重写equals方法要同步重写hashcode,具体的怎么写却不知道

接下来就主要说一下,具体的怎么实现(小白围观,老鸟勿扰)

其实开场的两句话也是这个意思

场景:

当你需要实现你自己的对象上的逻辑相等时,需要重写equals方法

比如一个学生类

name,age,sex,class…等多重属性

假设就是public student{   //这么一个类

name

age

sex

class

}

(简写一下,不要较真…)

 

用自然语言说的话,就是姓名,性别,年龄,班级一样,在这个类上的话,我们就可以认为两个对象是相等的了

对吧

换成java语言就是

public boolean equals(Object obj) {

if (obj instanceof Student) {   
            Student student= (Student ) obj;   
                        if(this.name.equals(student.name) && this.age.equals(student.age)
                     &&this.sex.equals(student.sex)&&this.class.equals(student.class)        ){
                
                return true;
            }
            else{
                return false;
            }  
        //非该类实例,直接返回false
        } else{
            
            return false;
        }

}

很简单,比较相等,至少得是学生..不是直接返回false

如果是学生实例,就比较一下,姓名年龄性别班级,都相等了就是相等了

 

怎么保障重写equals方法后,这两个对象实例的hashcode也是一样的呢?

所有的hashcode都返回一样的值?答案是可以的在某些情况下,但是某些情况下你就要悲剧了,所以当然不要

常用的办法是用:判断相等的条件  用到的属性  来重写

直白点就是:利用刚才使用到的姓名 性别 年龄 班级 这几个属性的值来重写hashcode

使用它们的组合方式

可以使用这样子的形式

a1*属性1的int形式+a2 属性2的int形式+….

a为系数

所谓属性的int形式,大家要知道hashcode都是数值

这样子才能保障最后的结果也是一个int值,简单就这么理解吧

而且还有就是比如string已经有了他自己的hashcode实现了,可以直接调用的

比如我们的例子

我们可以这样子

 

 

public int hashCode() {
    // TODO Auto-generated method stub
    //根据判断是否相等的属性,来重写hashCode
     return ( this.name.hashCode() + this.sex.hashCode()+age+this.class.hashcode() );

}

系数可以随便,你甚至都可以用this.name.hashCode() *age

形式上可以变化多端

但是要注意几个条件就好了

1,相同的对象的hashcode肯定是相同的

2,最后生成的结果不能大于int的取值范围

3,尽可能的科学保证不是随随便便的一个对象hashcode都相等

 

友情提示:

[1]. HashSet判断删除添加元素等操作依据的是被操作元素所在的类的hashCode()equals( )这两个方法。

[2]. ArrayList做同等的操作,依据的仅仅是equals( )方法