簡體   English   中英

Java語言中使用的散列函數

[英]Hashing function used in Java Language

我知道Java對HashMaps或HashTables有很好的內置支持。

有沒有人知道Java語言使用了什么樣的哈希函數或技術?

是否可以調整這些功能,以便能夠使它們更加特定於某個應用程序,從而提高性能並縮短訪問時間?

非常感謝閱讀!

Java允許您覆蓋類的hashCode()方法,以使用散列算法,該算法不僅適合您的應用程序,而且適用於您的各種類型:

public class Employee {

   private int id;
   // Default implementation might want to use "name" for as part of hashCode
   private String name; 

   @Override
   public int hashCode() {
     // We know that ID is always unique, so don't use name in calculating 
     // the hash code.
     return id;
   }
}

發瘋。

http://www.docjar.com/html/api/java/util/HashMap.java.html

此外,您始終可以將調整大小閾值和初始內存使用量設置為您需要的大小,這將減少地圖幾乎已滿時的放置時間。 如果您的地圖是線程化的,那么通過使用ConcurrentHashmap也可以獲得巨大的性能提升。

就像一個注釋,如果你要覆蓋hashCode,你也應該重寫equals。

根據存儲在集合中的對象計算哈希碼。 它使用標准算法計算(根據Effective Java)。 有關詳細信息,請參閱。

您確實可以基於每個對象覆蓋哈希碼方法。 實現hashcode方法的最佳方法是通過HashcodeBuilder(whcih是Commons Lang框架的一部分,請參見此處:

http://commons.apache.org/lang/

有關hashcode的更多詳細信息,請參閱此文章:

http://www.ibm.com/developerworks/java/library/j-jtp05273.html

希望有所幫助。

我知道Java對HashMaps或HashTables有很好的內置支持。

完全缺乏哈希映射文字的語法,我真的不會說......

無論如何,正如其他人所指出的那樣,由各個類來指定他們的hashCode()應該是什么(默認是內存地址的哈希值)。 如果你自己實現了,請確保遵循hashCode()方法的約定(特別是它需要與equals()一致),否則該類將不適用於HashMap中的鍵。

您還可以直接查看j ava.util.HashMap和朋友的源代碼,看看它們是如何實現的。 例如,HashMap使用一個桶數組,並且桶可以使用鏈表溢出。

為了進一步閱讀,您可能希望查看可以由多個線程同時安全訪問的ConcurrentHashMap,以及TreeMap,它提供了一種為可以排序(而不一定是散列)的鍵構建映射的方法。 。

一般來說,不值得擔心標准JDK類的哈希函數。 即使你可以覆蓋String(你不能),實際上它的哈希函數實際上總是“足夠好”。 可能有一些例外 - 例如某些類(如BigInteger和集合)每次通過循環遍歷它們包含的每個元素來計算它們的哈希代碼,這在某些情況下是非常虛假的 - 但是你多久關鍵一次這些實例班?

為了設計自己類的哈希碼,你要做的就是在整數范圍內“隨機”傳播哈希碼。 為此,您通常希望“混合”對象中連續字段的位(您可能對我的網站上的一篇文章感興趣,該文章以圖形方式說明了字符串哈希代碼如何混合位 )。 將當前散列乘以奇數(通常是素數),然后添加下一個元素的散列通常可以很好地作為第一次嘗試。 (但是,例如,當組合的數字/哈希碼往往在其較低位中具有零時,這種方法可能會出現問題 - 通常沒有實際的哈希函數,絕對保證在所有情況下都能正常工作。)

然后,您可以考慮測試您的哈希碼。 生成一系列隨機對象(甚至使用一些真實的對象),計算它們的哈希碼,然后從底部開始,比如16位哈希碼,然后看看你得到了多少次沖突。 檢查您獲得的沖突數量是否與您希望偶然獲得哈希沖突數量大致相符。 例如,如果您在哈希代碼(&0xffff)的底部16位之后,那么在1000個隨機對象之后,您預計會發生大約8次沖突。 2000年之后,你會發現大約30次碰撞。

就性能而言,在某種程度上,我認為獲得分布均勻的哈希碼通常比犧牲散列計算速度的哈希質量更有益。

你應該遵守一個“hashCode / equals contract”,它表示根據equals()方法彼此相等的對象必須提供相同的hashCode()值。 然而,並不要求具有相同hashCode的所有對象也相等。 您應該查看http://java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode() ,它會告訴您詳細信息。

一開始可能有點難以理解所涉及的對稱性,但絕對值得理解它,除非你急於在你的應用程序中將對象放入HashMap和不遵守那些的朋友時有奇怪的行為合同。

我還建議獲取Effective Java的副本,並閱讀hashCode / equals的章節以完全理解它。

我建議,如果你知道你需要快速哈希,就是使用另一個實現:嘗試快速工具( http://fastutil.dsi.unimi.it/ )或特洛伊( http://trove4j.sourceforge.net/ )。 它們顯然更快,但是類型特定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM