equal

Object:

    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

默认情况下:
    从超类Object继承而来的equals方法与"=="是完全等价的,比较的都是对象的内存地址。
    但我们可以重写equals方法,使其按照我们的需求的方式进行比较,如String类重写了equals方法,使其比较的是字符的序列,而不再是内存地址。


父类:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof Person) {
            Person p = (Person) obj;
            return super.equals(p) && name.equals(p.name);
        }
        return false;
    }

子类:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof Student) {
            Student s = (Student) obj;
            return super.equals(s) && name.equals(s.name);
        }
        return super.equals(obj);
    }

比较的元素不能是子类中声明的新变量(拥有统一的语义),否则不能进行混合比较。


如果equals的语义在每个子类中有所改变,就使用getClass检测:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return name.equals(student.name);
    }

hashCode

Object:

    @HotSpotIntrinsicCandidate
    public native int hashCode();


Student类:

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

    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

    public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }


重写equals()的同时还得重写hashCode(),主要是针对映射相关的操作(Map接口):

    如果两个对象通过调用equals方法是相等的,那么这两个对象调用hashCode方法必须返回相同的整数。


Map接口的类会使用到键对象的哈希码:

    Java使用hashCode()来获取对象的哈希码,其值就是对象的存储地址,这个方法在Object类中声明,因此所有的子类都含有该方法。

    当我们调用put方法或者get方法对Map容器进行操作时,都是根据键对象的哈希码来计算存储位置的,

    因此如果我们对哈希码的获取没有相关保证,就可能会得不到预期的结果。


如果两个对象通过调用equals方法是不相等的,不要求这两个对象调用hashCode方法必须返回不同的整数(HashMap)。
但是对不同的对象产生不同的hash值可以提高哈希表的性能。