Hashtable源码分析
转自https://blog.csdn.net/duoduo18up/article/details/80167074
1.定义
public class Hashtable<K,V> extends Dictionary<K,V>implements Map<K,V>,Cloneable,java.io.Serializable
继承自Dictionary。
- Dictionary是一个抽象父类,功能和Map一样,但过时了,官方推荐使用Map接口来替代。
实现了Map接口,以及Cloneable,Serializable接口。
2.和HashMap的区别
2.1 null值的问题
Hashtable的键(key)和值(value)均不能为null
/**
* 将key和value加入到map中,明显标明,
* value不能为null。如果key为null,则会报NullPointerException异常
* */
public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) {throw new NullPointerException();}// Makes sure the key is not already in the Hashtable.Entry<?,?> tab[] = table;int hash = key.hashCode();//很直接的利用hashCode去除table.length,然后取长度。int index = (hash & 0x7FFFFFFF) % tab.length;@SuppressWarnings("unchecked")Entry<K,V> entry = (Entry<K,V>)tab[index];//链表后面有数据for(; entry != null ; entry = entry.next) {if ((entry.hash == hash) && entry.key.equals(key)) {//hash相同且equals,那么就连在后面,是用链表的方式。V old = entry.value;entry.value = value;return old;}}//第一个,链表后面没有数据。addEntry(hash, key, value, index);return null;
}
关于value,明显有if判断,不能为null。
如果key为null,则也直接在计算hashCode的时候就会报空指针异常。
2.2 计算table数组索引值的方法
int hash=key.hashCode();//直接用hashcode%n
int index=(hash&0x7FFFFFFF)%tab.length
而HashMap中:
int index=e.hash%n;
hash值的计算方法不同,很直接地利用hashCode去除table.length,然后取余数。
2.3 Hashtable是线程安全的
因为Hashtable中的大多数方法都是加了synchronized关键字,所以同一时刻只能有一个线程进入其方法,故是线程安全的。
2.4initialCapacity和loadFactor
HashMap中:initialCapacity=16,loadFactor=0.75;
Hashtable中:initialCapacity=11,loadFactor=0.75;
2.5解决冲突的方式
HashMap:链表/红黑树
- 冲突数量<8,以链表方式解决冲突
- 冲突数量>=8,将冲突的Entry转换为红黑树进行存储
- 又当冲突数量<6时,有转换为链表进行存储
Hashtable:只有链表
2.6 扩容的额度
HashMap中:一旦扩容,都是扩展到2的倍数。因为这样有利于计算数组索引值。即,和计算数组索引结合起来
Hashtable中:一次性扩展为oldCapacity*2+1
/*** 一次扩展是,old*2+1
*/
@SuppressWarnings("unchecked")
protected void rehash() {int oldCapacity = table.length;Entry<?,?>[] oldMap = table;// overflow-conscious codeint newCapacity = (oldCapacity << 1) + 1;if (newCapacity - MAX_ARRAY_SIZE > 0) {if (oldCapacity == MAX_ARRAY_SIZE)// Keep running with MAX_ARRAY_SIZE bucketsreturn;newCapacity = MAX_ARRAY_SIZE;}Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];modCount++;//新的threshold值。取newCapacity*loadFactor的小值。threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);table = newMap;for (int i = oldCapacity ; i-- > 0 ;) {for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {Entry<K,V> e = old;old = old.next;int index = (e.hash & 0x7FFFFFFF) % newCapacity;e.next = (Entry<K,V>)newMap[index];newMap[index] = e;}}
}
先扩展,再把就数组里面的元素一个一个添加到新的里面。
注意:这里取hash而不是e.hash,而仍然是key.hashCode计算保留下来的值。
Hashtable源码分析相关推荐
- Java源码详解三:Hashtable源码分析--openjdk java 11源码
文章目录 注释 哈希算法与映射 线程安全的实现方法 put 操作 get操作 本系列是Java详解,专栏地址:Java源码分析 Hashtable官方文档:Hashtable (Java Platfo ...
- Java集合:Hashtable源码分析
1. 概述 上次讨论了HashMap的结构,原理和实现,本文来对Map家族的另外一个常用集合HashTable进行介绍.HashTable和HashMap两种集合非常相似,经常被各种面试官问到两者的区 ...
- 【Java源码分析】HashTable源码分析
类的定义 public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Clon ...
- Java集合之Hashtable源码分析
概述 Hashtable也是基于哈希表实现的, 与map相似, 不过Hashtable是线程安全的, Hashtable不允许 key或value为null. 成员变量 Hashtable的数据结构和 ...
- Java学习集合源码分析
集合源码分析 1.集合存在的原因 可以用数组来表示集合,那为什么还需要集合? 1)数组的缺陷 在创建数组时,必须指定长度,一旦指定便不能改变 数组保存必须是同一个类型的数据 数组的增加和删除不方便 ...
- ConcurrentHashMap实现原理及源码分析
ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对HashMap的实现原理还不甚了解,可参考我的另一篇文章HashMap实现原理及源码分析),Con ...
- Redis 数据结构-字典源码分析
2019独角兽企业重金招聘Python工程师标准>>> 相关文章 Redis 初探-安装与使用 Redis 数据结构-字符串源码分析 本文将从以下几个方面介绍 前言 字典结构图 字典 ...
- Java源码详解六:ConcurrentHashMap源码分析--openjdk java 11源码
文章目录 注释 类的继承与实现 数据的存储 构造函数 哈希 put get 扩容 本系列是Java详解,专栏地址:Java源码分析 ConcurrentHashMap 官方文档:ConcurrentH ...
- Java源码详解二:HashMap源码分析--openjdk java 11源码
文章目录 HashMap.java介绍 1.HashMap的get和put操作平均时间复杂度和最坏时间复杂度 2.为什么链表长度超过8才转换为红黑树 3.红黑树中的节点如何排序 本系列是Java详解, ...
最新文章
- Linux入门-7 Linux管道、重定向以及文本处理
- IDEA插件-生成对象所有set方法--->GenerateAllSetter
- 抽象类(c++细节篇九)
- html文件已传入服务器,把html文件上传到云服务器
- 程序猿值得看的几个技术网站(记录)
- 蓝桥杯 ADV-221 算法提高 7-1用宏求球的体积
- 用Word2007写Blog
- 仿51 job 省市二级联动
- MATLAB代码:基于分布式优化的多产消者非合作博弈能量共享
- docker安装网易云音乐(yesplaymusic)
- 雨滴win7计算机路径,Rainmeter雨滴桌面Win7打不开怎么办?
- element ui表单必填_elementUI 表单校验切换必填和非必填
- 避免过多if - else的新姿势:策略模式、工厂 + 策略
- 如何安装华为路由器模拟环境ENSP
- OS和Linux笔记
- 高校BBS最HOT的100个笑话(不看保证后悔终身)
- 深入剖析 grep 命令
- Android学习 书籍
- ROS自定义msg类型及使用
- python抓取网站88titienmae88中的“图片区”的第一页的所有图片
热门文章
- CentOS 7 使用Google-Authenticator进行多因素认证
- 外媒称Windows 10是一辆“广告大巴车”
- [Leetcode] Permutations 全排列
- [转]自适应网页设计(Responsive Web Design)
- jvm在不同系统中的最大内存空间地址
- 【计网】计算机网络期末总复习-谢希仁(个人总结)理论概念
- 【杂项】CUDA下找不到CUDA Sample文件
- linux fedora 35 彻底卸载idea2021.2.2
- linux shell 判断文件是否存在
- gorm框架:user role用户角色一对一关联Model编写