簡體   English   中英

Java默認使用什么散列函數,我們可以覆蓋默認行為嗎?

[英]What hashing function does Java use by default and can we override the default behavior?

我將通過Cormen等人的視頻介紹算法,並討論了幾種散列函數。 我想知道Java默認使用什么散列函數?對於用作鍵的不同類型的對象,散列函數實際上是否有所不同? Collections框架中是否有api讓我們編寫自己的哈希算法?

java中的每個對象都有一個返回哈希的public int hashCode()方法。 每個對象都可以通過覆蓋該方法以自己的方式自由地實現它。 如果未覆蓋該方法,則使用默認的Object#hashCode方法

您可以查看各種對象的源代碼,以了解它在JDK中的實現方式。 這是String的hashCode例如(第1494行)。

某些集合可以在對象的hashCode方法之上添加額外的散列層。 例如,當對象的hashCode分布不好時,HashMap會這樣做以提高性能。

您可以隨時在任何類中覆蓋它...喜歡

 @override
 public int hashCode()
 { 
 //new implementation 
 }

http://mindprod.com/jgloss/hashcode.html

默認的hashCode()方法使用Object的32位內部JVM(Java虛擬機)地址作為其hashCode。

但是,如果在垃圾回收期間將Object移動到內存中,則hashCode保持不變。 這個默認的hashCode不是很有用,因為要在HashMap中查找一個Object,你需要與鍵/值對最初歸檔的完全相同的密鑰對象。

通常,當你去查找時,你沒有原始的密鑰對象本身,只有一些密鑰的數據。 因此,除非您的密鑰是String,否則幾乎總是需要在密鑰類上實現hashCode和equals方法。

Object.hashCode()是一種本機方法。

這取決於您使用的對象的類型。 對於在您自己的類中實現的任何對象,您始終可以覆蓋默認的hashCode()方法。

注意,你應該始終遵守hashCode()equals()之間的協議,如hashCode()javadoc中所述:

如果兩個對象根據equals(Object)方法相等,則對兩個對象中的每一個調用hashCode方法必須生成相同的整數結果。

有關更多信息,請閱讀此條目

Java中的每個類型都定義了hashCode()方法,就像它在Object hashCode()返回一個int HashMap實現中,它再次散列結果並僅使用較低位使其在0到size -1的范圍內。 請注意,在Sun JDK中,大小始終為2 x ,x為某個整數。

Java庫是開源的,您可能在您的開發機器上有一個副本。

在Sun JDK 6中,我上面提到的第二個哈希是

/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

您可以通過查看您感興趣的類上的hashCode()函數來查找第一個哈希。

Java中的所有類都繼承自java.lang.Object ,通過這樣做,它們繼承了返回int的方法hashCode() 默認方法返回VM創建的一些(或多或少)唯一值(將其視為對象的內存地址,即使這並不完全正確)。 當您實現自己的類時,您可以覆蓋該方法以執行您想要的任何操作。 但是,您應該注意hashCodeequals方法是一致的,並且您應該知道,通常哈希代碼不是唯一的,因此無論您做什么,都希望不同對象的哈希代碼之間發生沖突。

Collections框架通常使用hashhCode()方法來散列Hashtables等的東西。可以想象其他庫中的其他數據結構使用顯式散列函數,但這不會發生在Collections框架中。

暫無
暫無

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

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