1. 程式人生 > >equals(),hashCode()的區別和聯絡

equals(),hashCode()的區別和聯絡

1.首先討論==問題:

看一組比較,包括基本型別和其包裝類,引用型別之間的比較

String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1==str2);//false

String str3 = "hello";
String str4 = "hello";
System.out.println(str3==str4);//true
System.out.println(str1==str3);//false;

Integer it1 = 12;
Integer it2 = 12;
System.out.println(it1==it1);//true

Integer it3 = new Integer(12);
Integer it4 = new Integer(12);
System.out.println(it3==it4);//false
System.out.println(it1==it3);//false

int it5 = 12;
System.out.println(it1==it5);//true
System.out.println(it3==it5);//true

==比較的是物件的引用,凡是與new的物件比較,必須是同一物件,特殊情況是基本資料型別和String的常量池,String常量池裡面的值唯一,因此值相同,地址相同,==成立;基本資料型別和其包裝類比較,會自動拆裝箱,值相同==就成立

2.equals()方法

原生的equals()比較的也是引用地址,但是重寫之後可以比較堆裡面的值內容是否相等,一般用於集合元素的比較,避免重複插入。下面是重寫的String的equals()方法

public boolean equals(Object anObject) {  
    if (this == anObject) {  //同一物件
        return true;  
    }  
    if (anObject instanceof String) {  
        String anotherString = (String)anObject;  
        int n = count;  
        if (n == anotherString.count) {  //長度相同
        char v1[] = value;  
        char v2[] = anotherString.value;  
        int i = offset;  
        int j = anotherString.offset;  
        while (n-- != 0) {  
            if (v1[i++] != v2[j++])  
            return false;  
        }  
        return true;  //每個對應位置的字元相等
        }  
    }  
    return false;  //長度不等 直接返回
    }  

3.hashCode()方法

根據物件的值計算其物理儲存位置,即hash值,對於值equals的物件,其hashCode一定相等,但是即使值不相等,也可能得到相同的hash值,因此在同一hash值的位置形成了連結串列,可以看出,每次new出一個物件,直接計算出其hash值,然後尋找對應位置上,再使用equals方法比較,是否已存在值就可以知道物件是否重複了,這樣比依次呼叫equals()與集合中的每個元素比較要節省很多時間。hash地址允許衝突,但是設計的越分散效能越好。

4.equals()與hashCode()的比較

兩個物件equals,則hashCode一定相等,因為計算方式一樣

兩個物件不equals,則hashCode不一定不相等,因為可能存在地址衝突

兩個物件hashCode相等,物件不一定equals,因為可能存在地址衝突

兩個物件hashCode不相等,物件一定不equals