Java中重写equals就必须重写hashCode吗?

事件

今天同事跑过来问我,我用list判断是否包含对象,我只重写了equals方法,居然可以正确判断,不是说重写equals就必须重写hashCode么?我让她看看ArrayList的 contains 方法,然后她就明白了。

== :它计算的是操作数的值之间的关系,如果是基本数据类型,值相等即可,如果是引用类型,内存地址要一样
equals : Object 的 实例方法,比较两个对象的content是否相同
hashCode : Object 的 native方法 , 获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数

文字表达太空洞了,我们直接上代码

不重写 equals 也不重写 hashCode

class Student {
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public static void main(String[] args) {
        Student student1 = new Student("张三", 1);
        Student student2 = new Student("张三", 2);
        System.out.println("==:" + (student1 == student2));
        System.out.println("equals:" + (student1.equals(student2)));
        System.out.println("student1 hashCode:" + student1.hashCode() + ",student2 hashCode:" + student2.hashCode());
        Set<Student> set = new HashSet<>();
        set.add(student1);
        set.add(student2);
        System.out.println("set的大小:" + set.size());
        List<Student> list = new ArrayList<>();
        list.add(student1);
        System.out.println("list contains:" + list.contains(student2));
    }
}

运行结果:

==:false
equals:false
student1 hashCode:30852576,student2 hashCode:20929316
set的大小:2
list contains:false

没有重写equals 所以也是false
hashSet 无序,不能重复,大小是2说明 是两个对象
list 是有序集合,可重复 包含 是两个对象,所以是false

只重写 equals 不重写 hashCode

此时equals等,hashCode不等

class Student {
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj.getClass() != this.getClass()) {
            return false;
        }
        return this.getName().equals(((Student) obj).getName());
    }
    public static void main(String[] args) {
        Student student1 = new Student("张三", 1);
        Student student2 = new Student("张三", 2);
        System.out.println("==:" + (student1 == student2));
        System.out.println("equals:" + (student1.equals(student2)));
        System.out.println("student1 hashCode:" + student1.hashCode() + ",student2 hashCode:" + student2.hashCode());
        Set<Student> set = new HashSet<>();
        set.add(student1);
        set.add(student2);
        System.out.println("set的大小:" + set.size());
        List<Student> list = new ArrayList<>();
        list.add(student1);
        System.out.println("list contains:" + list.contains(student2));
    }
}

==:false
equals:true
student1 hashCode:30852576,student2 hashCode:20929316
set的大小:2
list contains:true

点击继续阅读