Hashtable实现原理及源码分析
Hashtable简介
和HashMap一样,Hashtable也是一个散列表,存储的内容是键值对(key-value)映射。
Hashtable在Java中的定义为:
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
从源码中可以看出,Hashtable继承于Dictionary,实现了Map、Cloneable、Serializable接口。其中Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。Hashtable的函数都是同步的,这意味着它是线程安全的。key、value都不可以为null。此外,Hashtable中的映射不是有序的。
Hashtable是通过“拉链法”实现的哈希表。它包括几个重要的成员变量:table, count, threshold, loadFactor, modCount。
- table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的“key-value键值对”都是存储在Entry数组中的。
- count是Hashtable的大小,它是Hashtable保存的键值对的数量。
- threshold是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值=”容量*加载因子”。
- loadFactor就是加载因子。
- modCount是用来实现fail-fast机制的
部分源码解析:
构造方法
// 指定“容量大小”和“加载因子”的构造函数
public Hashtable(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal Load: "+loadFactor);
if (initialCapacity==0)
initialCapacity = 1;
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int)(initialCapacity * loadFactor);
}
// 指定“容量大小”的构造函数
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}
// 默认构造函数
public Hashtable() {
// 指定容量大小为11,加载因子为0.75
this(11, 0.75f);
}
// 构造一个与给定的 Map 具有相同映射关系的新哈希表
public Hashtable(Map<? extends K, ? extends V> t) {
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}
put() 方法
public synchronized V put(K key, V value) {
// 确保value不为空,否则抛异常
if (value == null) {
throw new NullPointerException();
}
//确保key不在hashtable中
//首先,通过hash方法计算key的哈希值,并计算得出index值,确定其在table[]中的位置
//其次,迭代index索引位置的链表,如果该位置处的链表存在相同的key,则替换value,返回旧的value
Entry tab[] = table;
int hash = key.hashCode();
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扩容操作
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 将Hashtable中index位置的Entry(链表)保存到e中
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
get() 方法
其过程首先通过hash()方法或得key的哈希值,然后根据hash值得等index所有,然后迭代链表,返回匹配的key对应的value,没有的话返回null。
public synchronized V get(Object key) {
Entry tab[] = table;
// 得等hash值
int hash = key.hashCode();
// 计算索引值
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)) {
return e.value;
}
}
return null;
}
Hashtable实现原理及源码分析的更多相关文章
- ConcurrentHashMap实现原理及源码分析
ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...
- HashMap和ConcurrentHashMap实现原理及源码分析
HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...
- HashMap实现原理及源码分析之JDK8
继续上回HashMap的学习 HashMap实现原理及源码分析之JDK7 转载 Java8源码-HashMap 基于JDK8的HashMap源码解析 [jdk1.8]HashMap源码分析 一.H ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- (转)ReentrantLock实现原理及源码分析
背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...
- 【转】HashMap实现原理及源码分析
哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...
- 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造
原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论 自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...
- 《深入探索Netty原理及源码分析》文集小结
<深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de
- 【OpenCV】SIFT原理与源码分析:关键点描述
<SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SI ...
随机推荐
- .NET Core2.0应用IdentityServer4
IdentityServer4能解决什么问题 假设我们开发了一套[微博程序],主要拥有两个功能:[登陆验证].[数据获取] 随后我们又开发了[简书程序].[知乎程序],它们的主要功能也是:[登陆验证] ...
- Java中如何实现类似C++结构体的二级排序
1:实现Comparable接口 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; ...
- poj 1986 Distance Queries 带权lca 模版题
Distance Queries Description Farmer John's cows refused to run in his marathon since he chose a pa ...
- Python 获取文件的创建时间,修改时间和访问时间
# 用到的知识# os.path.getatime(file) 输出文件访问时间# os.path.getctime(file) 输出文件的创建时间# os.path.getmtime(file) 输 ...
- JS身份证验证
window.checkIdcard = function (idcard) { var errors = new Array( "yes", "请检查输入的证件号码是否 ...
- Solaris 11, gcc 的安装
注意点在于, 头文件在另外一个包system/header里,需要另外安装 pkg pkg install system/header
- mycat分布式mysql中间件(自增主键)
一.全局序列号 全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求.全局序列号的语法符合标准SQL规范,其格式为:nex ...
- Confluence 6 设置公共访问备注
你不能为匿名用户赋予空间管理员或者限制权限. 你可以让用户自行注册你的 Confluence 站点,同时也可以选择其他的用户注册选项,比如邀请用户注册等.请查看:Add and Invite User ...
- pandas的concat函数和append方法
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, nam ...
- 关于Floyd求解最小环的问题
最近学习了floyd的奇妙用处,求解最小环,自己的领悟写在了纸上. 对于一个最小环,显然至少要包含三个点(此处不把两个点的回路称之为环) 从大体上考虑的话,一定有一个点与左右两侧的点是直接连接的(即不 ...