美文网首页Java
再论:关于 equals 和 hashCode

再论:关于 equals 和 hashCode

作者: shengjk1 | 来源:发表于2020-03-15 12:28 被阅读0次

上篇 关于 equals 和 hashCode 关于 equals 和 hashCode 的基本性质已经论述过了。

1.什么时候应该覆盖 equals?
我们知道 equals 默认比较的内存地址,即是否为同一个对象。如果类具有了自己特有的逻辑相等,即属性值等,的概念时,并且超类没有覆盖或者覆盖了单不满足子类需求的情况下重写 equals。

但对于类似枚举类这样的 class 而言,每个属性最多只存在一个对象,逻辑相等与内存地址相等时一样的,不需要重写。

2.为什么要覆盖 equals( hashCode) ?

/**
 * @author shengjk1
 * @date 2020/3/14
 */
public class TestEquals {
    public static void main(String[] args) {
        HashMap<Student, String> map = new HashMap<>();
        Student student = new Student(16, "小明");
        map.put(student, "a");
        Student student1 = new Student(16, "小明");
        System.out.println(map.containsKey(student1));
    }
}

class Student {
    private int age;
    private String name;
    
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    //  @Override
//  public boolean equals(Object o) {
//      if (this == o) return true;
//      if (o == null || getClass() != o.getClass()) return false;
//      Student student = (Student) o;
//      return age == student.age &&
//              Objects.equals(name, student.name);
//  }
//
    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
}

结果

false

这完全不是我们想要的,我们希望的是 map.containsKey(student1) 为true。但为什么是 false 呢?通过源码我们可以知道 应为 equals 不等,导致的。同理,对于 hashCode 也是如此。

3.是否是任何时候都需要覆盖 equals 和hashCode?
答案是 否定的。
还记得上一篇说过的吗,JDK 内部就有违背 equals hashCode 一致性规则的。另外的话,hashCode 仅仅针对 hash 表来说才有用。

/**
 * @author shengjk1
 * @date 2020/3/14
 */
public class TestEquals {
    public static void main(String[] args) {
        HashMap<Student, String> map = new HashMap<>();
        Student student = new Student(16, "小明");
        map.put(student, "a");
        Student student1 = new Student(16, "小明");
        System.out.println("map " + map.containsKey(student1));
        
        ArrayList<Student> students = new ArrayList<>();
        students.add(student);
        System.out.println("list " + students.contains(student1));
    }
}

class Student {
    private int age;
    private String name;
    
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }
//
//  @Override
//  public int hashCode() {
//      return Objects.hash(age, name);
//  }
}

结果

map false
list true

对于 list 而言,根本就不需要 比较hashCode,我们也违背了 equals 与 hashCode 的一致性,但对于 students.contains(student1) 结果就是正确的

4.总结
1.java 集合内部比较对象是否相等一般用的都是 equals ,所以 equals 是要尽量重写的。
2.而对于 hashCode 来说,对于 hash table 来说是必须要重写的,其他的可以不重写。

相关文章

  • 再论:关于 equals 和 hashCode

    上篇 关于 equals 和 hashCode 关于 equals 和 hashCode 的基本性质已经论述过了。...

  • 第五章

    #1 【强制】关于hashCode和equals的处理,遵循如下规则# 1.重写equals,即必须重写hashCode

  • 阿里Java编程规约【五】 集合处理

    【强制】关于 hashCode 和 equals 的处理,遵循如下规则:1) 只要重写 equals ,就必须重写...

  • 阿里规约集合处理

    【强制】关于 hashCode 和 equals 的处理,遵循如下规则:1) 只要重写 equals,就必须重写 ...

  • 第9条:覆盖equals时总要覆盖hashCode

    equals方法和hashCode方法均是Object对象的方法。Object中关于hashCode约定的规范如下...

  • java容器

    equals和hashCode equals和hashcode间的关系:如果两个对象相同(即equals比较返回t...

  • 关于hashcode和equals

    这篇文要清楚这三个问题:1、hashcode,equals内容是什么?2、只重写equals()但不重写hashC...

  • 关于 equals 和 hashCode

    主要是说一下 equals 和 hashcode 1.hashCode 此方法主要是用来支持 hash table...

  • 关于hashCode和equals

    在Object类中,有hashCode()和equals()方法,而任何类都是Object的子类,同样也继承了这两...

  • 集合处理规约

    【强制】关于 hashCode 和 equals 的处理,遵循如下规则:1) 只要覆写 equals,就必须覆写 ...

网友评论

    本文标题:再论:关于 equals 和 hashCode

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