Java中哈希表(Hashtable)是如何實現的


Java中哈希表(Hashtable)是如何實現的

Hashtable中有一個內部類Entry,用來保存單元數據,我們用來構建哈希表的每一個數據是Entry的一個實例。假設我們保存下面一組數據,第一列作為key, 第二列作為value。

{“one", 1}
{"two", 2}
{"three", 3}
{"four", 4}

寫一個演示程序:

import java.util.Hashtable;

public class Main {

    public static void main(String[] args) {
        Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();
        numbers.put("one", 1);
        numbers.put("two", 2);
        numbers.put("three", 3);
        numbers.put("four", 4);
        numbers.put("five", 5);

        Integer n = numbers.get("two");
        Integer nn = numbers.get("six");
        
        if(n != null)
            System.out.println(n);
            System.out.println(nn);
    }
}

Hashtable內部用一個Entry數組table,來保存所有的數據。

當我們插入一個新的Entry對象時,即用Hashtable的put(key, value)方法。
在put方法里:
計算key的hash值
計算index值,作為數組table的下標,即table[index]
哈希表中根據key的索引值index,創建了多個bucket,所有index值一樣的Entry對象,構造成一個鏈接表存放在同一個bucket里。既然是一個鏈接表,根據數據結構知識,自然我們的Entry對象需要有一個指向下一個對象的指針,即Entry對象需要有這些屬性:key,value,next。

如何構造hash函數?

hash值,如何生成?對於每個對象的hash值,要保證每一個hash值都不一樣。
在Java SDK中, String的hashCode方法如下:

//hash的初始值為0
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;
}

index值,如何生成?這里要求保存的數據是均勻的分配在每一個bucket中,Hashtable源碼中采用%操作(mod)使數據分布在編號為0~10的bucket中。
Hashtable中put方法的源碼如下:

private int hash(Object k) {
    // hashSeed will be zero if alternative hashing is disabled.
    return hashSeed ^ k.hashCode();
}

public synchronized V put(K key, V value) {
    ... ...
    int hash = hash(key);
    int index = (hash & 0x7FFFFFFF) % tab.length;
    ... ...
}

這樣數據存儲到哈希表之后,當我們要查找或者說獲取一個對象時候,采用同樣的方式可以快速的找到我們需要的對象。

哈希表可以快速的找到一個元素。在有大量的數據的時候,比普通的順序查找要快的多。
假設有10000條數據,如果采用順序查找,最壞的情況下需要對比10000次能找到,最好的情況是1次。平均查找次數位(10000+1)/2,大約為5000次。
換一種方式,如果把10000條數據通過hash值索引分成10組,每一組有1000條數據,這樣每一次只需要先確定是哪一組,然后在1000條數據里查找,這樣最壞的情況是1000次, 最好的情況是1次。平均查找次數為(1000+1)/2 ,大約為500次。比上面的方法快了5倍。

我們常用的5種算法有順序查找,二分法查找,二叉排序樹查找,哈希表法查找,分塊查找。Java的Hashtable即是用了哈希表法查找。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM