HashTable
参考:https://blog.csdn.net/qq_33206732/article/details/80338354
HashTable是线程安全的,因为几乎所有的public方法都是synchronized的
- Hashtable也是一个散列表,它存储的内容是键值对。基于Dictionary类
- 存储数据: 首先判断value是否为空,为空则抛出异常;计算key的hash值,并根据hash值获得key在table数组中的位置index,如果table[index]元素不为空,则进行迭代,如果遇到相同的key,则直接替换,并返回旧value;否则,我们可以将其插入到table[index]位置。
- key和value都不允许为null,Hashtable遇到null,直接返回NullPointerException。
- 较HashMap速度慢
Hashtable
和HashMap一样,Hashtable也是一个散列表,它存储的内容是键值对。默认容量为11,装载因子为0.75
public Hashtable() {
this(11, 0.75f);
}
成员变量
Hashtable是通过”拉链法”实现的哈希表。它包括几个重要的成员变量:table, count, threshold, loadFactor, modCount。
table:是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的”key-value键值对”都是存储在Entry数组中的。
count:是Hashtable的大小,它是Hashtable保存的键值对的数量。
threshold:是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值=”容量*加载因子”。
loadFactor:就是加载因子。
modCount:是用来实现fail-fast机制的(用于防止在读取过程中,有更新操作,如果有更新操,该参数会修改,然后读取操作会报错)。
构造方法
Hashtable一共提供了4个构造方法:
public Hashtable(int initialCapacity, float loadFactor): 用指定初始容量和指定加载因子构造一个新的空哈希表。useAltHashing为boolean,其如果为真,则执行另一散列的字符串键,以减少由于弱哈希计算导致的哈希冲突的发生。
public Hashtable(int initialCapacity):用指定初始容量和默认的加载因子 (0.75) 构造一个新的空哈希表。
public Hashtable():默认构造函数,容量为11,加载因子为0.75。
public Hashtable(Map<? extends K, ? extends V>
t):构造一个与给定的 Map 具有相同映射关系的新哈希表。
其存储数据流程如下:
1.判断value是否为空,为空则抛出异常;
2.计算key的hash值,并根据hash值获得key在table数组中的位置index,如果table[index]元素不为空,则进行迭代,如果遇到相同的key,则直接替换,并返回旧value;
3.否则,我们可以将其插入到table[index]位置。
从上面可以看出,其存储流程和HashMap相似。
获取数据
相比较于put方法,get方法则简单很多。其过程就是首先通过hash()方法求得key的哈希值,然后根据hash值得到index索引(上述两步所用的算法与put方法都相同)。然后迭代链表,返回匹配的key的对应的value;找不到则返回null。
HashTable源码:
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
。。。。。
}
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = hash(key);
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
return null;
}
/**
* Removes the key (and its corresponding value) from this
* hashtable. This method does nothing if the key is not in the hashtable.
*
* @param key the key that needs to be removed
* @return the value to which the key had been mapped in this hashtable,
* or <code>null</code> if the key did not have a mapping
* @throws NullPointerException if the key is <code>null</code>
*/
public synchronized V remove(Object key) {
Entry tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
return oldValue;
}
}
return null;
}
实例:
Hashtable table = new Hashtable();
18 // 添加操作
19 table.put("one", r.nextInt(10));
20 table.put("two", r.nextInt(10));
21 table.put("three", r.nextInt(10));
22
23 // 打印出table
24 System.out.println("table:"+table );
25
26 // 通过Iterator遍历key-value
27 Iterator iter = table.entrySet().iterator();
28 while(iter.hasNext()) {
29 Map.Entry entry = (Map.Entry)iter.next();
30 System.out.println("next : "+ entry.getKey() +" - "+entry.getValue());
31 }
内部Entry类:
private static class Entry<K,V> implements Map.Entry<K,V> {
int hash;
final K key;
V value;
Entry<K,V> next;
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
上一篇: 查找_找出数组中最大的两个数
下一篇: 求数组中的最大值和次大值
推荐阅读
-
java语法ArrayList、LinkedList、HashSet、HashMap、HashTable、Collection、Collections详解
-
对比Hashtable,HashMap,TreeMap,谈谈对HashMap的理解
-
PHP 源代码分析 Zend HashTable详解第1/3页
-
C#中遍历Hashtable的4种方法
-
java中集合(LinkedList、HashSet、HashMap、HashTable、Collection、Collections)
-
java中Hashtable和HashMap的区别分析
-
C#中HashTable的定义与使用方法
-
C#中遍历Hashtable的4种方法
-
php中hashtable实现示例分享
-
遍历Hashtable 的几种方法