HashTable实现
来源:互联网 发布:转盘抽奖软件注册码 编辑:程序博客网 时间:2024/05/07 08:50
1.
散列函数的实现算法:Doug Lea's supplemental secondaryHash function (inlined).
碰撞解决:采用拉链法,实现的过程基本同<算法>
拉链法:数组+链表(每个数组的item是链表)实现
2.构造函数
public HashMap() {
table = (HashMapEntry<K, V>[]) EMPTY_TABLE;
// threshold:resize数组大小的上限值(一般取最大容量的3/4)
threshold = -1; // Forces first put invocation to replace EMPTY_TABLE
}
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1];// MINIMUM_CAPACITY==4
3.put函数
@Override public V put(K key, V value) {
...
int hash = secondaryHash(key); // 散列函数Doug Lea's supplemental
HashMapEntry<K, V>[] tab = table; // table保存键值对的map集合
int index = hash & (tab.length - 1); // table的大小都是2^n,每次容量扩大都是两倍扩大
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) { // 之前有put该map(key,value),则修改value的值
preModify(e); // 该函数在LinkedHashMap有覆盖实现,调用makeTail
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
/ 之前没有put该map(key,value)
// No entry for (non-null) key is present; create one
modCount++;
if (size++ > threshold) {
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
addNewEntry(key, value, hash, index);
return null;
}
// 容量扩大一倍
private HashMapEntry<K, V>[] doubleCapacity() {
HashMapEntry<K, V>[] oldTable = table;
int oldCapacity = oldTable.length;
int newCapacity = oldCapacity * 2;// 容量扩大策略:扩大两倍
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
// 重新hash原来旧的table
for (int j = 0; j < oldCapacity; j++) {// 对每个链表进行重新hash
/*
* Rehash the bucket using the minimum number of field writes.
* This is the most subtle and delicate code in the class.
*/
HashMapEntry<K, V> e = oldTable[j];
if (e == null) {
continue;
}
// 重新hash每个item对应的链表的每个元素
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
newTable[j | highBit] = e;
// 变量链表每个元素
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
return newTable;
}
// 创建新表格
private HashMapEntry<K, V>[] makeTable(int newCapacity) {
@SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable
= (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];
table = newTable;
threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
return newTable;
}
// 添加一个新的hash元素:新元素插入到链表头
void addNewEntry(K key, V value, int hash, int index) {
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}
HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
this.key = key;
this.value = value;
this.hash = hash;
this.next = next;
}
4.get函数--相对put函数更简单
public V get(Object key) {
...
// Doug Lea's supplemental secondaryHash function (inlined).
// Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
int hash = key.hashCode();
hash ^= (hash >>> 20) ^ (hash >>> 12);
hash ^= (hash >>> 7) ^ (hash >>> 4);
HashMapEntry<K, V>[] tab = table;
// 通过hash找到链表,并遍历链表每个元素,找到key对应value
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
5.remove函数
/*
从链表中删除一个元素
*/
@Override public V remove(Object key) {
int hash = secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index], prev = null;
e != null; prev = e, e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
if (prev == null) {
tab[index] = e.next;
} else {
prev.next = e.next;
}
modCount++;
size--;
postRemove(e); // 通知子类,父类删除了该元素. LinkedHashMap有实现该函数
return e.value;
}
}
return null;
}
散列函数的实现算法:Doug Lea's supplemental secondaryHash function (inlined).
碰撞解决:采用拉链法,实现的过程基本同<算法>
拉链法:数组+链表(每个数组的item是链表)实现
2.构造函数
public HashMap() {
table = (HashMapEntry<K, V>[]) EMPTY_TABLE;
// threshold:resize数组大小的上限值(一般取最大容量的3/4)
threshold = -1; // Forces first put invocation to replace EMPTY_TABLE
}
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1];// MINIMUM_CAPACITY==4
3.put函数
@Override public V put(K key, V value) {
...
int hash = secondaryHash(key); // 散列函数Doug Lea's supplemental
HashMapEntry<K, V>[] tab = table; // table保存键值对的map集合
int index = hash & (tab.length - 1); // table的大小都是2^n,每次容量扩大都是两倍扩大
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) { // 之前有put该map(key,value),则修改value的值
preModify(e); // 该函数在LinkedHashMap有覆盖实现,调用makeTail
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
/ 之前没有put该map(key,value)
// No entry for (non-null) key is present; create one
modCount++;
if (size++ > threshold) {
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
addNewEntry(key, value, hash, index);
return null;
}
// 容量扩大一倍
private HashMapEntry<K, V>[] doubleCapacity() {
HashMapEntry<K, V>[] oldTable = table;
int oldCapacity = oldTable.length;
int newCapacity = oldCapacity * 2;// 容量扩大策略:扩大两倍
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
// 重新hash原来旧的table
for (int j = 0; j < oldCapacity; j++) {// 对每个链表进行重新hash
/*
* Rehash the bucket using the minimum number of field writes.
* This is the most subtle and delicate code in the class.
*/
HashMapEntry<K, V> e = oldTable[j];
if (e == null) {
continue;
}
// 重新hash每个item对应的链表的每个元素
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
newTable[j | highBit] = e;
// 变量链表每个元素
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
return newTable;
}
// 创建新表格
private HashMapEntry<K, V>[] makeTable(int newCapacity) {
@SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable
= (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];
table = newTable;
threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
return newTable;
}
// 添加一个新的hash元素:新元素插入到链表头
void addNewEntry(K key, V value, int hash, int index) {
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}
HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
this.key = key;
this.value = value;
this.hash = hash;
this.next = next;
}
4.get函数--相对put函数更简单
public V get(Object key) {
...
// Doug Lea's supplemental secondaryHash function (inlined).
// Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
int hash = key.hashCode();
hash ^= (hash >>> 20) ^ (hash >>> 12);
hash ^= (hash >>> 7) ^ (hash >>> 4);
HashMapEntry<K, V>[] tab = table;
// 通过hash找到链表,并遍历链表每个元素,找到key对应value
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
5.remove函数
/*
从链表中删除一个元素
*/
@Override public V remove(Object key) {
int hash = secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index], prev = null;
e != null; prev = e, e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
if (prev == null) {
tab[index] = e.next;
} else {
prev.next = e.next;
}
modCount++;
size--;
postRemove(e); // 通知子类,父类删除了该元素. LinkedHashMap有实现该函数
return e.value;
}
}
return null;
}
0 0
- HashTable实现
- HashTable实现
- HashTable实现
- 实现HashTable
- hashtable实现 -- 参考leveldb hashtable
- HashTable实现 中
- javascript 实现hashtable集合
- Hashtable(完整实现)
- HashTable实现一
- HashTable的实现
- HASHTABLE的内部实现
- HashTable实现购物车
- Java的Hashtable实现
- C语言实现 HashTable
- Hashtable 的实现原理
- HashTable的实现测试
- HashTable的C++实现
- HashTable原理与实现
- nyoj16 矩形嵌套
- c++实验5-数组分离
- npm 设置proxy
- 第4章 数组上课示例
- c++作业5
- HashTable实现
- 【华为OJ】【011-数字颠倒】
- 数据库连接池的作用
- LinkedHashMap实现
- LruCache实现
- 【华为OJ】【012-字符串反转】
- ThreadLocal实现
- 大数据技术学习路线指南
- Laravel5.2多图上传的实现以及上传七牛