public native int hashCode()
hashCode()的作用是獲取哈希碼,也稱為散列碼游两;它實際上是返回一個int整數(shù)砾层。這個哈希碼的作用是確定該對象在哈希表中的索引位置。hashCode()定義在JDK的Object.java中器罐,這就意味著Java中的任何類都包含有hashCode()函數(shù)梢为。另外需要注意的是Object的hashCode方法是本地方法,也就是用c或者c++實現(xiàn)的,該方法通常用來將對象的內存地址轉換為整數(shù)之后返回铸董。
散列表存儲的是鍵值對(key-value)祟印,特點是能根據(jù)“鍵”快速的檢索出對應的“值”,這其中就利用到了散列碼(可以快速找到所需要的對象)
為什么要有hashCode
以HashSet如何檢查重復為例:當把對象假如HashSet時粟害,HashSet會先計算對象的hashCode值來判斷對象加入的位置蕴忆,同時也會與其他已經加入的對象的hashCode值做比較,如果沒相符的hashCode悲幅,HashSet會假設對象沒有重復出現(xiàn)套鹅。但是如果發(fā)現(xiàn)有相同hashCode值得對象,這時就會調用equals方法來檢查hashcode相等的對象是否真的相同汰具,如果兩者相同卓鹿,HashSet就不會讓其加入操作成功。如果不同的話留荔,就會重新散列到其他位置吟孙,這樣我們就大大減少了equals的 次數(shù),相應就大大提高了執(zhí)行效率聚蝶。
hashCode()和equals的相關規(guī)定
1.如果兩個對象相等杰妓,則hashCode一定也是相同的
2.兩個對象相等,對兩個對象分別調用equals方法都返回true
3.兩個對象有相同的hashCode值碘勉,但是也不一定是相等的
4.因此巷挥,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
5.hashCode()的默認行為是對堆上的對象產生獨特值验靡。如果沒有重寫hashCode()倍宾。則該class的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數(shù)據(jù))
為什么兩個對象有想相同的hashcode值,他們也不一定是相等的?
因為hashCode()所使用的雜湊算法也許剛好會讓多個對象傳回相同的雜湊度,越糟糕的雜湊算法越容易碰撞误澳,但這也和數(shù)據(jù)值域分布的特性有關(所謂碰撞也就是指的是不同對象得到相同hashCode)
對于HashSet,如果HashSet在對比的時候初厚,同樣的hashcode有多個對象,它會使用equals來判斷是否真的相同孙技,也就是說hashcode只是用來縮小查找成本产禾。
==與equals
==是判斷兩個對象的地址是不是相等。即判斷兩個對象是不是同一個對象(基本數(shù)據(jù)類型==比較的是值牵啦,引用類型==比較的是內存地址)
equals是判斷兩個對象是否相等亚情。
1.類沒有覆蓋equals方法,則通過equals比較該類的兩個對象時哈雏,等價于通過==比較兩個對象
2.類覆蓋了equals方法楞件,一般我們都覆蓋equals方法來判斷兩個對象的內容相等衫生,則返回true
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 為一個引用
String b = new String("ab"); // b為另一個引用,對象的內容一樣
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 從常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一對象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}
說明:
String中的equals方法是被重寫過的土浸,因為Object的equals方法比較的對象的內存地址罪针,則String的equals方法比較的是對象的值。
當創(chuàng)建String類型的對象時黄伊,虛擬機會在常量池中查找有沒有已經存在的值和要創(chuàng)建的值相同的對象泪酱,如果有就把它賦值給當前引用,如果沒有就再常量池中重新創(chuàng)建一個String對象还最。