項目地址: https://github.com/kelin-xycs/HashTableLibhtml
爲何會想要本身寫一個 Hash 表, 之前也想過 Hash 表 的 原理, 以爲很神奇,git
不過最近的 直接緣由 是 最近在搞 ILBC, 這能夠認爲是一個 編譯器 項目,github
有關 ILBC, 見 《ILBC 規範》 http://www.javashuo.com/article/p-hsmtjoox-s.html ,數組
編譯器 裏 會 須要 快速 的 查找 成員(變量 、字段 、類 、 方法 / 函數), 好比 檢驗 成員 是否重名, 以及 對 成員 的 訪問 的 編譯工做 。函數
也包括 運行期查找成員(反射 / 動態連接) 。性能
固然 ILBC 裏使用的 Hash 表 會用 C 語言 寫, 此次寫的 項目 是 用 C# 寫的, 在 原理 上 實現了一下 。spa
具體的邏輯 看代碼 就行, 代碼很少, 大約 350 行 。 ^^設計
不過有一點說明一下, 就是能夠調用 HashTable 的 htm
public HashTable(int initCapacity)blog
這個 構造函數 重載 來 指定 initCapacity ,
也能夠調用
public HashTable(int initCapacity, double whenEnlarge, double enlargeRatio)
這個 構造函數 重載 來 指定 initCapacity, whenEnlarge, enlargeRatio ,
initCapacity 表示 new HashTable 時 的 初始 的 Hash 表 容量, 容量 是指 Hash 表 內部 存儲元素 的 數組 的 長度,
whenEnlarge 表示 當 元素(鍵值對) 的 數量 達到 容量 的 百分之幾 時, 要對 Hash 表 擴容(增大容量), 擴容 就是 按照 新的 容量 申請一個 數組, 把 原來的 數組 的 元素 從新 添加到 新數組 裏, 注意 這裏的 添加 不是 簡單的複製, 而是 把 元素(鍵值對) 從新 添加(Add) 到 Hash 表, 在 添加(Add) 時 會 從新計算 key 的 Hash 值 並 根據 key 的 Hash 值 計算 鍵值對 在 數組 裏的 位置(下標 ( index )) 。
enlargeRatio 表示 擴容 時 要 擴大多少, 即 增長的容量 相對於 原來的容量 所佔 的 百分比 。
若是不想本身指定 initCapacity, whenEnlarge, enlargeRatio , 也能夠調用 無參 構造函數
public HashTable()
無參 構造函數 使用 默認的 initCapacity, whenEnlarge, enlargeRatio ,
initCapacity 的 默認值 是 100 ,
whenEnlarge 的 默認值 是 0.8 ,
enlargeRatio 的 默認值 是 0.3 。
若是 知道 元素(鍵值對) 的 數量 或者 大概數量, 能夠 指定 InitCapacity , 這樣能夠 避免 或 減小 擴容 , 提升效率 。
注意 若是 指定 Capacity 是 100, whenEnlarge 是 0.8, 那麼 當 元素(鍵值對) 數量 達到 100 * 0.8 = 80 後, 再 添加 鍵值對 時, 就會 擴容 。
如今的設計 只涉及到 擴容, 沒有 「縮容」, 縮容 是指 當 元素(鍵值對) 數量 減小到 必定程度 時, 會 減小 Capacity , 把 元素(鍵值對) 放到一個 長度更小 的 數組 裏 。
縮容 的 部分 能夠仿照 擴容 來寫, 但要注意 whenDeLarge 和 whenEnlarge 之間 應該要有 顯著 的 差距, 若是 二者 相等 或者 相近, 可能會 剛 擴容 又 縮容, 剛 縮容 又 擴容, 頻繁 擴容 縮容 致使 性能低下 。
不過 通常場合 好像 不須要 縮容 。