JVM里面hashtable和hashmap实现原理
JVM里面hashtable和hashmap实现原理
在hashtable和hashmap是java里面常见的容器类,
是Java.uitl包下面的类,
那么Hashtable和Hashmap是怎么实现hash键值对配对的呢,我们看看jdk里面的源码,分析下Hashtable的构造方法,put(K, V)加入方法和get(Object)方法就大概明白了。
一、Hashtable的构造方法:Hashtable(int initialCapacity, float loadFactor)
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);
}
这个里面米内有什么好说的,要注意的是table一个是实体数组,输入的initialCapacity表示这个数组的大小,而threshold 是一个int值,其中loadFactor默认是0.75,就是说明,当table里面的值到75%的阀值后,快要填满数组了,就会自动双倍扩大数字容 量。
而Entry<K,V> 来自与
private static class Entry<K,V> implements Map.Entry<K,V> {
int hash;
K key;
V value;
Entry<K,V> next;
是一个单项链表,

上图就是Hashtable的表,
二、put(K, V)加入方法
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 = 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 ld = e.value;
e.value = value;
return old;
}
}modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
这个看看起来很长,只要注意三点就可以了,
1.index,index是键值的hashcode和0x7FFFFFFF的&运算,然后根据数组长度求余值。这样可以定出所在队列名称,
2、
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V ld = e.value;
e.value = value;
return old;
}
}
for语句里面是让e在tab某个队列名为index单项链表里面遍历,第几个单项链表的定义由index定义,看看该队列是否已经有同样的值,如果有,就返回该值。
3、如果没有,则加入
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
三、get(Object),获得
public synchronized V get(Object key) {
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)) {
return e.value;
}
}
return null;
}
这个就很好理解了 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;
}
}
在该队里面遍历,根据hash值获得具体值。
总结下,一个是根据index确定队列,在由hash值获得具体元素值。
看完了hashtable, 我们在来看看hashMap
hashMap可以算作是hashtable的升级版本, 最早从1.2开始有的.
但是, 两者之间最主要的不同有两点.
1. hashMap的读写是unsynchronized, 在多线程的环境中要注意使用
而hashtable是synchronized
这两者的不同是通过在读写方法上加synchronized关键字来实现的.
第二个不同是hashMap可以放空值, 而hashtable就会报错.
JVM里面hashtable和hashmap实现原理的更多相关文章
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...
- (转)HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)
HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...
- [转帖]HashMap、HashTable、ConcurrentHashMap的原理与区别
HashMap.HashTable.ConcurrentHashMap的原理与区别 http://www.yuanrengu.com/index.php/2017-01-17.html 2017年1月 ...
- HashMap、Hashtable、ConcurrentHashMap的原理与区别
同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...
- HashMap、Hashtable、ConcurrentHashMap的原理与区别(简述)
HashTable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相 ...
- 面试必备:HashMap、Hashtable、ConcurrentHashMap的原理与区别
同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...
- Hashmap与Hashtable的区别及Hashmap的原理
Hashtable和HashMap有几个主要的不同:线程安全以及速度.仅在你需要完全的线程安全的时候使用Hashtable,而如果你使用Java 5或以上的话,请使用ConcurrentHashMap ...
- 集合 HashMap 的原理,与 Hashtable、ConcurrentHashMap 的区别
一.HashMap 的原理 1.HashMap简介 简单来讲,HashMap底层是由数组+链表的形式实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表 ...
随机推荐
- web前端开发前景怎么样?
对于web前端开发,对现今前端的发展,中国的发展还很落后,中国没有Jquery,没有Node.js,其中最主要的一点是,中国的前端比较封锁,大家都没有分享的觉悟.回头看看,那些发展比较快的行业.软件, ...
- Fragment+Activity传递数据
自己经常使用的知识点,每次到要用的时候都还要再查一次才能懂得使用,终于体会到总结的必要性了. Activity传递数据给Fragment Bundle bundle_fragment=new Bund ...
- Wireshark 过滤条件
做应用识别这一块经常要对应用产生的数据流量进行分析. 抓包采用wireshark,提取特征时,要对session进行过滤,找到关键的stream,这里总结了wireshark过滤的基本语法,供自己以后 ...
- mfc非模态对话框
按照我们的之前的做法,先新建工程. 把基本的内容都添加上. 形成这样一个样子: 并且进行试运行,让程序能够完成加法运算. 值的注意的是,静态文本那里要改一下名字,否则无法将成员变量进行添加. 前期准备 ...
- 关于egit的日常操作总结
$git fetch -p --prune -p -- remove any remote tracking branches that no longer exist remotely prune的 ...
- C语言中 指针和数组
C语言的数组表示一段连续的内存空间,用来存储多个特定类型的对象.与之相反,指针用来存储单个内存地址.数组和指针不是同一种结构因此不可以互相转换.而数组变量指向了数组的第一个元素的内存地址. 一个数组变 ...
- 浅试WebStorm配置Node.js开发环境
web前端开发IDE一直喜欢用WebStorm,这里简单介绍如何用WebStorm搭建一个Node.js开发环境. 首先,需要在本地安装好node.js,以及npm包管理工具.你也可以吧node.js ...
- Unity3d不支持vistual studio2012?用vs2012打开unity c#脚本进行编码的方法。
unity3d是支持vs2010的,但是有很多开发者反应,unity3d中的C#脚本不能用vs2012打开.我想了一下,先进入存放C#脚本的目录,在设置里面C#文件的打开方式,选择用vs2012打开, ...
- Android 使用BaseAdapter 插入不同类型数据
在使用过程有时要在listview中插入不同类型的数据,比如说position=0的位置插入,广告,其它列表显示数据的情况. 一定要重写两种方法 @Override public int getIte ...
- SQL Server调优系列进阶篇 - 如何重建数据库索引
随着数据的数据量的急剧增加,数据库的性能也会明显的有些缓慢这个时候你可以考虑下重建索引或是重新组织索引了. DBCC SHOWCONTIG('表名') 可以查看当前表的索引碎情况. 重建索引 方法一: ...