谈谈Java中的==、equals与hashCode的区别

1.概述

  • ==: 该操作符生成的是一个boolean结果,它计算的是操作数的值之间的关系
  • equals: Object的实例方法,比较两个对象的content是否相同
  • hashCode: Object的native方法,获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int类型整数

2.关系操作符==

2.1基本数据类型变量

在Java中有八种基本数据类型:

  • 浮点型: float(4 byte), double(8 byte)
  • 整型: byte(1 byte), short(2 byte), int(4 byte), long(8 byte)
  • 字符型: char(2 byte)
  • 布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只能够取字面值“true”和“false”)

对于这八种基本数据类型的变量,变量直接存储的是“值”。因此,在使用关系操作符 == 来进行比较时,比较的就是“值”本身。要注意的是,浮点型和整型都是有符号类型的(最高位仅用于表示正负,不参与计算【以 byte 为例,其范围为 -2^7 ~ 2^7 - 1,-0即-128】),而char是无符号类型的(所有位均参与计算,所以char类型取值范围为0~2^16-1)。

2.2引用类型变量

在Java中,引用类型的变量存储的并不是“值”本身,而是与其关联的对象在内存中的地址。比如下面这行代码:

String str;

这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 而通过 new 来产生一个对象,并将这个对象和str进行绑定:

str = new String("HelloWorld");

那么 str1就指向了这个对象,此时引用变量str中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”HelloWorld”。这里面的引用和 C/C++ 中的指针很类似。

2.2小结

因此,对于关系操作符 ==:

  • 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的值是否相等
  • 若操作数的类型是引用数据类型,则该关系操作符判断的是左右两边操作数的内存地址是否相同。也就是说,若此时返回true,则该操作符作用的一定是同一个对象。

3.equals

看看equals()方法在Object类中的定义:

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

在String、Double等封装类中,已经重载(overriding)了Object类的equals()方法,于是有了另一种计算公式,是进行内容的比较。
比如在String类中:

public int hashCode() { 
    int h = hash; 
    if (h == 0) { 
        char val[] = value; 
        int len = count; 
        for (int i = 0; i < len; i++) { 
            h = 31*h + val[off++]; 
        } 
        hash = h; 
    } 
    return h; 
} 

4.hashCode

在Object类中的定义为:

public native int hashCode();

是一个本地方法,返回的对象的地址值。
但是,同样的思路,在String等封装类中对此方法进行了重写。方法调用得到一个计算公式得到的 int值.

5.hashCode和equlas的关系

  • 1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
  • 2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)
  • 原因:从散列的角度考虑,不同的对象计算哈希码的时候,可能引起冲突,大家一定还记得数据结构中。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。