项目地址: 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 之间 应该要有 显著 的 差距, 若是 二者 相等 或者 相近, 可能会 刚 扩容 又 缩容, 刚 缩容 又 扩容, 频繁 扩容 缩容 致使 性能低下 。
不过 通常场合 好像 不须要 缩容 。