hashcode 的作用

來源:互聯網
上載者:User

原文出處:http://blog.chenlb.com/2009/09/hashcode-effect.html

Java 對象 Hashcode 的作用是什嗎?可以聯想資料結構的雜湊表(散列表)、雜湊函數。Object.hashCode() 就是一個雜湊函數,用來計算散列值以實現雜湊表這種資料結構。

看下雜湊表結構:

雜湊表

在一個數組中儲存物件時,通過 hashCode 得到的雜湊值來計算數組的索引位置(通常是求餘運算),然後根據這個索引位置進行存取。多個對象計算出來的索引位置相同(叫hash衝突)時,用鏈表儲存。衝突怎麼保證取到的就是自己呢?那麼就要用到 Object.equals() 方法。

所以要把Object Storage Service在像 hash table類似的資料結構(比如:HashSet)中,hashCode 與 equals 要成對實現。

Java Object hashCode api

返回該對象的雜湊碼值。支援該方法是為雜湊表提供一些優點,例如,java.util.Hashtable 提供的雜湊表。
hashCode 的常規協定是:
  • 在 Java 應用程式執行期間,在同一對象上多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是對象上 equals 比較中所用的資訊沒有被修改。從某一應用程式的一次執行到同一應用程式的另一次執行,該整數無需保持一致。
  • 如果根據 equals(Object) 方法,兩個對象是相等的,那麼在兩個對象中的每個對象上調用 hashCode 方法都必鬚生成相同的整數結果。
  • 以下情況 是必需的:如果根據 equals(java.lang.Object) 方法,兩個對象不相等,那麼在兩個對象中的任一對象上調用 hashCode 方法必定會產生不同的整數結果。但是,程式員應該知道,為不相等的對象產生不同整數結果可以提高雜湊表的效能。

實際上,由 Object 類定義的 hashCode 方法確實會針對不同的對象返回不同的整數。(這一般是通過將該對象的內部地址轉換成一個整數來實現的,但是 JavaTM 程式設計語言不需要這種實現技巧。)

上面的協定來看,一個對象的狀態(這些狀態不一定是所有欄位,根據業務來看)沒有改變時,多次調用 hashCode 必定相等。但是不同的對象可以有相等的 hashCode,不過盡量使不同的對象有不相等的 hashCode 可以提高雜湊表的效能。

看下 Java Hashtable 的 get 與 put 實現:

  1. public synchronized V get(Object key) {  
  2.     Entry tab[] = table;  
  3.     int hash = key.hashCode();  
  4.     int index = (hash & 0x7FFFFFFF) % tab.length;  
  5.     for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  6.         if ((e.hash == hash) && e.key.equals(key)) {  
  7.         return e.value;  
  8.         }  
  9.     }  
  10.     return null;  
  11. }  

先根據 key.hashCode 找數組的索引位置 index,hash & 0x7FFFFFFF 保證是正數。然後順著找 hash 和 equals 相等的。衝突鏈越長效能就越差。

看 put 方法:

  1. public synchronized V put(K key, V value) {  
  2.     // Make sure the value is not null  
  3.     if (value == null) {  
  4.         throw new NullPointerException();  
  5.     }  
  6.   
  7.     // Makes sure the key is not already in the hashtable.  
  8.     Entry tab[] = table;  
  9.     int hash = key.hashCode();  
  10.     int index = (hash & 0x7FFFFFFF) % tab.length;  
  11.     for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  12.         if ((e.hash == hash) && e.key.equals(key)) {  
  13.         V old = e.value;  
  14.         e.value = value;  
  15.         return old;  
  16.         }  
  17.     }  
  18.   
  19.     modCount++;  
  20.     if (count >= threshold) {  
  21.         // Rehash the table if the threshold is exceeded  
  22.         rehash();  
  23.   
  24.             tab = table;  
  25.             index = (hash & 0x7FFFFFFF) % tab.length;  
  26.     }  
  27.   
  28.     // Creates the new entry.  
  29.     Entry<K,V> e = tab[index];  
  30.     tab[index] = new Entry<K,V>(hash, key, value, e);  
  31.     count++;  
  32.     return null;  
  33. }  

先看是否有相同的,有就替換。然後數組空間不夠,會重換分配空間並資料重新散列儲存。最後在衝突鏈頭上插入。

其它有用串連:通過分析
JDK 原始碼研究 Hash 儲存機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.