“==”、equals 和 hashCode 的区别

来源:互联网 发布:qq截图软件绿色版 编辑:程序博客网 时间:2024/05/17 15:19

1. “==”运算符

“==”运算符用来比较两个变量的值是否相等。要比较两个基本类型的数据或两个引用变量是否相等,只能使用“==”运算符。

  1. 两个基本类型的数据,使用“==”运算符来比较其对应的值是否相等。

  2. 两个引用变量(指向对象类型的变量),使用“==”运算符来比较两个变量是否指向同一个对象。

具体而言,如果两个变量是基本数据类型,可以直接使用“==”运算符来比较其对应的值是否相等。如果一个变量指向的数据是对象(引用类型),那么,此时涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存(栈内存),例如,对于赋值语句 String s = new String(),变量 s 占用一块存储空间,而 new String() 则存储在另一块存储空间里,此时,变量 s 所对应内存中的数值就是对象占用的那块内存的首地址。对于只想对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应内存中的数值是否相等(这两个对象是否指向同一块存储空间),这时候就可以用“==”运算符进行比较。但是,如果要比较这两个对象的内容是否相等,那么用“==”运算符就无法实现了。

2. equals( )方法

equals 是 Object 类提供的方法之一。,每一个 java 类都继承自 Object 类,所以每一个对象都具有 equals 这个方法。Object 类中定义的 equals( Object ) 方法是直接使用 “==”运算符比较的两个对象,所以
在没有覆盖 equals( Object ) 方法的情况下, equals( Object ) 与 “==”运算符一样,比较的是引用。

相比于“==”运算符,equals( Object )方法的特殊之处在于它可以被覆盖,所以可以通过覆盖equals( Object )方法让它不是比较引用而是比较数据的内容。

例如 String 类的 equals 方法是用于比较两个独立对象的内容是否相同,即堆中的内容是否相同,以下面代码为例:

public class StringTest {    public static void main(String[] args) {        String s1 = new String("Hello");        String s2 = new String("Hello");        System.out.println(s1==s2); // 比较的是引用        System.out.println(s1.equals(s2)); // 比较的是内容    }}/*Output:falsetrue*///~

如果一个类没有定义 equals( )方法,那么它将继承 Object 类的 equals( ) 方法, Object 类的 equals( ) 方法的实现代码如下:

    boolean equals( Object o ) {        return this == o;    }

从代码实现中可以看出,如果一个类没有定义自己的 equals( ) 方法,它默认的 equals( ) 方法(从 Object 类继承的)就是使用“==”运算符,也是在比较两个变量指向的对象是否是同一对象,此时使用 equals( ) 方法和使用 “==”运算符会得到相同的结果。

3. hashCode( )方法

hashCode( ) 方法是从 Object 类中继承过来的,它用来鉴定两个对象是否相等。Object 类中的 hashCode( ) 方法返回对象在内存中地址转换成的一个 int 值,所以如果没有重写 hashCode() 方法,任何对象的hashCode()方法都是不相等的。

虽然 equals( ) 方法也是用来判断连个对象是否相等的,但是它与 hashCode( ) 方法是有区别的。
一般来讲,equals( ) 方法是给用户调用的,如果需要判断两个对象是否相等,可以重写 equals( ) 方法,然后在代码中调用,这样就可以判断它们是否相等了。
对于 hashCode( ) 方法,用户一般不会去调用它,例如在 hashmap 中,由于 key 是不可以重复的,它在判断 key 是否重复时就是用了 hashCode( ) 方法,也用到了 equals( ) 方法。此处“不可以重复”指的是 equals( ) 和 hashCode( ) 只要有一个不等就可以了。所以,hashCode( ) 方法相当于是一个对象的编码,它与 equals( ) 方法的不同之处在于它返回的是 int 型,比较起来不直观。

注意:
一般覆盖 equals( ) 方法的同时也要覆盖 hashCode( ) 方法,否则,就会违反 Object.hashCode 的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类(HashMap、HashSet 和 Hashtable)结合在一起正常运行。

hashCode( ) 方法的返回值和 equals( ) 方法的关系如下
如果 x.equals( y )返回 true,即两个对象根据 equals 方法比较是相等的,那么调用这两个对象中任意一个对象的 hashCode( ) 都必须产生同样的整数结果。如果 x.equals( y ) 返回 false,即两个对象根据 equals( ) 方法比较是不相等的,那么 x 和 y 的 hashCode( ) 方法的返回值有可能相等,也有可能不相等。反之,hashCode( ) 方法的返回值不相等,一定能推出 equals( ) 方法的返回值也不相等,而 hashCode( ) 方法的返回值相等,equals 方法的返回值则可能相等,也可能不相等。

常见题型:
1. 假设有以下代码 String s = “hello”; String t = “hello”; char c[] = {‘h’,’e’,’l’,’l’,’o’},下列选项中返回 false 语句的是:(B)
A. s.equals(t)
B. t.equals(c)
C. s == t
D. t.equals(new String(“hello”))

2.下面程序的输出结果是什么?

    String s = "abc";    String s1 = "ab" + "c";    System.out.println(s == s1);

答案: true。“ab”+ “c” 在编译器就被转换为 “abc”,存放在常量区,因此输出结果为 true。

3.Set 里的元素是不能重复的,那么用什么方法来区分是否重复呢? 使用 “==”还是 equals() ?
答案:用 equals() 方法来区分元素是否重复。

0 0