[英]A faster hash function
我正在嘗試實現自己的哈希函數,我使用Java累加了每個字符串的ASCII碼。 我通過找到哈希表大小和總和的mod來找到哈希碼。 大小%總和。 我想知道在搜索字符串時是否有一種方法可以使用相同的過程來減少沖突?
提前致謝。
Java String.hashcode()在成為一個真正好的哈希函數和盡可能高效之間進行了權衡。 簡單地將字符串中的字符值相加並不是可靠的哈希函數。
例如,考慮兩個字符串dog
和god
。 由於它們都包含一個“ d”,“ g”和一個“ o”,因此僅涉及加法的方法將永遠不會導致不同的哈希碼。
約書亞·布洛赫 ( Joshua Bloch )實現了Java的絕大部分,他在他的《 有效的Java》一書中討論了String.hashCode()方法,並討論了在1.3之前的Java版本中如何僅考慮16個字符的String.hashCode()函數。在給定的字符串中。 它的運行速度比當前的實現要快一些,但在某些情況下卻導致令人震驚的糟糕性能。
通常,如果您的特定數據集定義非常明確,並且可以利用其中的某些唯一性,則可能可以實現更好的哈希函數。 對於通用弦,祝您好運。
我會看一下String和HashMap的代碼,因為它們的沖突率很低,並且不使用%
並處理負數。
從字符串來源
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
從HashMap的來源
/**
* Retrieve object hash code and applies a supplemental hash function to the
* result hash, 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.
*/
final int hash(Object k) {
int h = 0;
if (useAltHashing) {
if (k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h = hashSeed;
}
h ^= k.hashCode();
// 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);
}
由於HashMap的大小總是2的冪,因此您可以使用
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
和
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
return h & (length-1);
}
使用&
比%
快得多,並且由於長度為正數,因此僅返回正數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.