美文网首页
java 重写类的equals()和hashCode()方法

java 重写类的equals()和hashCode()方法

作者: zhy0324 | 来源:发表于2020-08-17 18:12 被阅读0次

今天在用阿里代码检查工具检查项目的时候,发现了一个警告
Map/Set的key为自定义对象时,必须重写hashCode和equals
说明为:

1) 只要重写equals,就必须重写hashCode。  
2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。  
3) 如果自定义对象做为Map的键,那么必须重写hashCode和equals。

下面是代码的写法(伪代码)

    public void methodDemo(){
        Set<ObjDemo> hashSet = new HashSet();
        hashSet.add(new ObjDemo("1","对象1"));
        hashSet.add(new ObjDemo("2","对象2"));
    }

ObjDemo类很简单

class ObjDemo{
    private String id;

    private String name;

    public ObjDemo(String id,String name){
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

为什么会报这个警告?

警告中也说明了,因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。

了解hashSet存储对象的方式,请参考:https://www.jianshu.com/p/6cab0fae2403

equals和hashCode的关系(这个是规定):
1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)

hashCode()方法是干什么的,这里提示了是重写,那么原来其实是有一个hashCode的,在Object类中,这里的hashCode()存放的是对象的内存地址
所以我们在存放对象进入hashSet的时候,如果不重写equals()和hashCode(),像下面这段代码

    public void methodDemo(){
        Set<ObjDemo> hashSet = new HashSet();
        hashSet.add(new ObjDemo("1","对象1"));
        hashSet.add(new ObjDemo("1","对象1"));
    }

其实我们逻辑上放进去的是一个对象,因为id、name都相等,但是,如果打断点或者写个测试方法去输出hashSet长度的时候,会发现在hashSet中却有两个对象,因为这两个对象的内存地址是不同的。所以要重写equals()和hashCode()方法。例如根据id来比较两个对象是否相等,以及根据id取hashCode,在ObjDemo中加入

    @Override
    public boolean equals(Object o) {
        if (o instanceof ObjDemo){
            ObjDemo obj = (ObjDemo)o;
            return id.equals(obj.id);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

这样往hashSet中放对象时就会根据id去判断,不会重复添加。

面试题:为什么重写equals()方法要重写hashCode()方法

从上面的规定可以知道,如果只重写了equals()方法不重写hashCode()方法,那么则违反了如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同

也可以把上面的代码中的hashCode()方法去掉,添加2个id为1的对象,set集合里的数据还是为2条。

所以得出结论:如果一个类重写了equals方法但是没有重写hashCode方法,那么该类无法结合所有基于散列的集合(HashMap,HashSet)一起正常运作。

相关文章

  • Java 比较相等

    Java Equals() 特性 Equals() 和 == 的区别 重写Equals方法 重写HashCode方法

  • Object类

    找对象的方式: Object 类: java规范:一般我们再重写equals方法的时候,我们都会重写hashCode方法

  • hashCode 与 equals

    “你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” ha...

  • EffectiveJava笔记[三]

    11、重写equals时重写hashCode方法 在每一个重写了equals方法的类中,应当重写这个类的hashC...

  • Java中重写equals方法为什么要重写hashcode方法?

    Java中重写equals方法为什么要重写hashcode方法?(转) == 与 equals的区别 如果两个引用...

  • Kotlin基础(6)-->数据类与单例类

    一、数据类 数据类通常需要重写equals(),hashCode(),toString()这几个方法。equals...

  • hashcode

    JAVA中重写equals()方法的同时要重写hashcode()方法 object对象中的 public boo...

  • Java的equals和hashCode方法

    对于equals和hashCode 方法,Java建议在重写时应当满足规定: 如果两对象equals为true,h...

  • Collection集合

    hashcode() 和 equals() 方法最好都同时重写 equals相等,hashcode一定相等 has...

  • 我对类重写Equals和HashCode的理解

    重写equals和hashcode的原因:   为了通过调用hashcode()和equals()方法来判断2个对...

网友评论

      本文标题:java 重写类的equals()和hashCode()方法

      本文链接:https://www.haomeiwen.com/subject/lkiqjktx.html