浅谈Java中的==,equals和hashCode

272 阅读2分钟

在Java或者Android开发中==和equals基本上是最常用的,但他们有什么区别,equals和hashCode又有什么联系呢?

== 是运算符,判断两个值是否相等


对于基本数据类型,内存中存放的就是他们的值,所以可以直接用==判断是否相等。

equals是Object类中的一个方法


对于对象类型,内存中存放的是对象的地址,所以如果直接用==来比较的话是比较的对象地址,如果为true,则一定是同一个对象。


内部也是通过==判断两个对象的地址是否相同

public boolean equals(Object obj) {
    return (this == obj);
}

而String类型的对象在使用equals方法的时候两个new出来的相同内容,对象不同,结果却为true,为什么呢,咱们来看下源码:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = length();
        if (n == anotherString.length()) {
            int i = 0;
            while (n-- != 0) {
                if (charAt(i) != anotherString.charAt(i))
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

可以看出,String对象重写了Object类的equals方法,在判断引用地址之后,又增加了类型和内容的判断。在这里,也能够体现出重写equals方法的原则:

  1. 先判断引用地址是否相同
  2. 在判断类型是否相同
  3. 最后判断内容是否相同

hashCode也是Object类中的一个方法

hashCode在集合类操作中使用,提高查询速度,系统用来快速检索对象来使用,不经常外在使用,可以被用来作为一个对象的唯一标识。

也可以被重写,可以参照String重写方式:

public int hashCode() {
    int h = hash;
    final int len = length();
    if (h == 0 && len > 0) {
        for (int i = 0; i < len; i++) {
            h = 31 * h + charAt(i);//递推公式
        }
        hash = h;
    }
    return h;
}

equals和hashCode在重写时有以下几个原则:

  1. equals相等时,hashCode必须相等;
  2. equals不等时,hashCode可能相等也可能不相等;
  3. hashCode不相等时,equals一定不相等。