Java Hashtable 源码(JDK8)
记录了HashMap也来看看Hashtable吧,最近打算换份实习,所以想看看书回顾一下,不然就快记不得了.....囧啊囧啊,记性太差怎么破???
Hashtable里面的一些变量:
Entry<?,?>[] table : HashTable采用"拉链法"实现哈希表,每一个Entry代表了一个键值对(key-value)。
transient int count:hashtable里面键值对的个数;
private int threshold:hashtable的阀值(threshols = capacity * loadFactor);
float loadFactor:加载因子;
transient int modCount :hashtable被修改的次数,用来实现fast-fail机制。fast-fail机制就是在并发集合中,其进行迭代操作时,若有其他线程对其进行结构性的修改,这时迭代器会立马感知到,并且立即抛出 ConcurrentModificationException异常。
Hashtable的定义如下:
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
...
}
可以看出Hashtable实现了Map接口,同时继承了Dictionary类。Map接口是将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。Dictionary 类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。每个键和每个值都是一个对象。在任何一个 Dictionary 对象中,每个键至多与一个值相关联。给定一个 Dictionary 和一个键,就可以查找所关联的元素。任何非 null 对象都可以用作键或值。
看看Hashtable常用的构造函数的实现:
默认的构造函数:容量为11,加载因子为0.75
public Hashtable() {
this(11, 0.75f);
}
用指定的初始容量和默认的加载因子构造:
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}
用指定的初始容量和指定的加载因子构造:
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数组
table = new Entry<?,?>[initialCapacity];
//计算table的阀值
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
}
再来看看Put方法和get方法:
首先是put方法,put方法的整个处理流程是:计算key的hash值,根据hash值获得key在table数组中的索引位置,然后迭代该key处的Entry链表(我们暂且理解为链表),若该链表中存在一个这个的key对象,那么就直接替换其value值即可,否则在将改key-value节点插入该index索引位置处。注意,hashtable是不允许null值的。
int index = (hash & 0x7FFFFFFF) % tab.length——>键的hash值可能为负数,通过一个“与”操作,先将hash值都转化正数,然后将得到的hash值与Hashtable的长度求余
//同步实现
public synchronized V put(K key, V value) {
// check value值是否为null
if (value == null) {
throw new NullPointerException();
} // Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
//计算key的hash值
int hash = key.hashCode();
//通过hash值来计算在table数组中的下表
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
//遍历,寻找该key,找到则替换旧值
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
//没有找到,则将该key加入
addEntry(hash, key, value, index);
return null;
}
private void addEntry(int hash, K key, V value, int index) {
//修改链表,modCount自增
modCount++; Entry<?,?> tab[] = table;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
} // Creates the new entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}
get方法也是同步的,具体的实现如下:
public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
//计算key的hash值
int hash = key.hashCode();
//通过hash值来计算在table数组中的下表
int index = (hash & 0x7FFFFFFF) % tab.length;
//遍历查找key,找到则返回key值所对应的的value
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
return null;
}
Java Hashtable 源码(JDK8)的更多相关文章
- [Java] Hashtable 源码简要分析
Hashtable /HashMap / LinkedHashMap 概述 * Hashtable比较早,是线程安全的哈希映射表.内部采用Entry[]数组,每个Entry均可作为链表的头,用来解决冲 ...
- Java - HashTable源码分析
java提高篇(二五)-----HashTable 在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,valu ...
- JAVA的HashTable源码分析
Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长.Hashtable ...
- 转:【Java集合源码剖析】Hashtable源码剖析
转载请注明出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元 ...
- 【Java集合源码剖析】Hashtable源码剖析
转载出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一 ...
- Java入门系列之集合Hashtable源码分析(十一)
前言 上一节我们实现了散列算法并对冲突解决我们使用了开放地址法和链地址法两种方式,本节我们来详细分析源码,看看源码中对于冲突是使用的哪一种方式以及对比我们所实现的,有哪些可以进行改造的地方. Hash ...
- java HashMap源码分析(JDK8)
这两天在复习JAVA的知识点,想更深层次的了解一下JAVA,所以就看了看JAVA的源码,把自己的分析写在这里,也当做是笔记吧,方便记忆.写的不对的地方也请大家多多指教. JDK1.6中HashMap采 ...
- Java集合源码学习(一)集合框架概览
>>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...
- 【转】Java HashMap 源码解析(好文章)
.fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...
随机推荐
- Java设置jre通过java new Date()得到的时间的时区
1.前提 由于公司有印尼的项目,该项目仅对印尼当地开放使用(公司在国内,用的是阿里云的ECS,但是阿里云在印尼没有服务器,所以就买了新加坡的服务器),印尼当地人用的是东七区的时间,所以比国内东八区的时 ...
- opencv——拟合圆
#include "stdafx.h" #include "cv.h" #include "highgui.h" #include &quo ...
- linux fdisk分区工具
fdisk来自IBM老牌分区工具,支持绝大多数操作系统,几乎所有的linux的发行版本都装有disk,包括linux的resure模式下的依然能够使用. fdisk是一个机遇MBR的分区工具,所有如果 ...
- 打开页面默认弹出软键盘,同时兼容iOS和Android
// 示例1 open_soft_keyboard({ input: "#username" }); // 示例2 open_soft_keyboard({ input: 'inp ...
- Decoding VOX Files in C# (Converting VOX Files to WAV Files)
I wrote a C# class to decode VOX files into WAV files. It follows the Dialogic ADPCM specificationst ...
- Python【filter、map、reduce】
filter和map和reduce map(function,iterable...) -> list 映射,对列表中的每个值操作 返回操作后的数值组成列表 # 给列表值+1 l = [1,2, ...
- WebSerervice webapi使用
WebSerervice webapi使用 1.传json参数: 2.返回json数据: 3.权限控制: Authorize特性:必须经过认证,请求头必须具有token信息 4.路由: 5.过滤器: ...
- idea maven新建struts2项目
环境: IDEA java1.8 struts2-core 2.5.18 一路下一步,名字自己随便填, 项目建好后修改pom.xml文件,加入struts2-core 添加tomcat: +号添加w ...
- [Winter Vacation] 语文实词虚词练习册答案
下载通道: [120个文言文实词小故事] [18个文言文虚词小故事] 120个文言文实词小故事 爱 楚人爱(宠爱)其子,虽爱(吝惜)钱财,于其子之求而无不应.其子成人,有陶氏之风独爱(喜爱)菊,众 ...
- AutoCAD.Net 实现创建wipeout遮罩实体
[CommandMethod("mywipeout")] public static void mywipeout() { // 获取当前文档和数据库 Document acDoc ...