Java源码之HashMap
一、HashMap和Hashtable的区别
(1)HashMapl的键值(key)和值(value)可以为null,而Hashtable不可以
(2)Hashtable是线程安全类,而HashMap为非线程安全类(HashMap是非synchronized,而Hashtable是synchronized)
(3)由于Hashtable是线程安全,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
源码解析
HasgMap

Hashtable

二、如何使HashMap线程安全
Map m = Collections.synchronizeMap(hashMap);
三、详解HashMap
HashMap两种声明方式
1. Map<String> hashMap = new HashMap<String>(); 2. HashMap<String> hashMap = new HashMap<String>();
异同:
优点:
①灵活,符合java中所倡导的面向接口编程,例如如果项目需求不继续使用HashMap,而是改成TreeMap时,可以Map<String> hashMap = new TreeMap<String>();
②第一种声明方式是:父类的引用指向子类的对象,是多态的一种表现形式,实现了多态,多态后就可以写出一段所有子类都通用的代码,当添加新的子类时,这段代码是不需要修改的。
父类的引用指向子类的对象的好处:多态、动态链接,向上转型。
缺点:
①无法调用HashMap特有的方法。
stackoverflow链接:http://stackoverflow.com/questions/1348199/
HashMap源码解析

链拉法
(1)put函数实现
①求key的hashcode(),然后再对key的hashcode求它的hash值
②如果发生Hash碰撞,则比较key值,如果还相等,以链表的形式放在同一个Bucket中,但不同Entry
③如果没发生Hash碰撞,直接放入Bucket中。
④ 如果binCount>=TREEIFY_THRESHOLD - 1,就会有链表编程红黑树(TREEIFY_THRESHOLD=8)
⑤如果节点存在(比较过hash与key),则直接覆盖旧value
⑥如果bucket达到临界值(超过load factor*current capacity),就进行扩容
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
static final int TREEIFY_THRESHOLD = 8;
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//计算是哪一个bucket,并把头节点返回p
if ((p = tab[i = (n - 1) & hash]) == null)
//如果该bucket为空,则新建节点,放入该bucket中
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
//key先比较hash值,如果hash值相等,再比较key值,如果hash与key都相等,则覆盖
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
//如果实例p是TreeNode类型,则放进红黑树种
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
//链表处理
else {
//通过循环来插入后续节点
for (int binCount = 0; ; ++binCount) {
//插入链表中,采用头插法,e = p.next,p.next=newNode,p = e;
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
//如果binCount>=7,就会有链表编程红黑树
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
//判断链表中是否循环到hash相同,key相同的Entry
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
//如果Hash值相同,且key相等,则覆盖
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
Java源码之HashMap的更多相关文章
- JAVA源码分析-HashMap源码分析(一)
一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...
- Java源码学习:HashMap实现原理
AbstractMap HashMap继承制AbstractMap,很多通用的方法,比如size().isEmpty(),都已经在这里实现了.来看一个比较简单的方法,get方法: public V g ...
- 浅析Java源码之HashMap
写这篇文章还是下了一定决心的,因为这个源码看的头疼得很. 老规矩,源码来源于JRE1.8,java.util.HashMap,不讨论I/O及序列化相关内容. 该数据结构简介:使用了散列码来进行快速搜索 ...
- Java源码阅读HashMap
1类签名与注释 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cl ...
- Java源码解析|HashMap的前世今生
HashMap的前世今生 Java8在Java7的基础上,做了一些改进和优化. 底层数据结构和实现方法上,HashMap几乎重写了一套 所有的集合都新增了函数式的方法,比如说forEach,也新增了很 ...
- JAVA源码分析-HashMap源码分析(二)
本文继续分析HashMap的源码.本文的重点是resize()方法和HashMap中其他的一些方法,希望各位提出宝贵的意见. 话不多说,咱们上源码. final Node<K,V>[] r ...
- 浅析Java源码之HashMap外传-红黑树Treenode(已鸽)
(这篇文章暂时鸽了,有点理解不能,点进来的小伙伴可以撤了) 刚开始准备在HashMap中直接把红黑树也过了的,结果发现这个类不是一般的麻烦,所以单独开一篇. 由于红黑树之前完全没接触过,所以这篇博客相 ...
- 【数据结构】8.java源码关于HashMap
1.hashmap的底层数据结构 众所皆知map的底层结构是类似邻接表的结构,但是进入1.8之后,链表模式再一定情况下又会转换为红黑树在JDK8中,当链表长度达到8,并且hash桶容量超过64(MIN ...
- java源码之HashMap和HashTable的异同
代码版本 JDK每一版本都在改进.本文讨论的HashMap和HashTable基于JDK 1.7.0_67 1. 时间 HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2.从 ...
随机推荐
- template.process(root, out)的用法(shiro项目中来的九)
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8" ...
- CentOS 7.x 防火墙开放端口相关用法记录
前言 防火墙对服务器起到一定的保护作用,所以了解一些相关的操作是很有必要的. 在CentOS 7.x中,有了一种新的防火墙策略,FireWall , 还记得在6.x中用的还是iptables. 这几天 ...
- BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)
BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...
- (luogu P4012)深海机器人问题 [TPLY]
网页链接 https://www.luogu.org/problemnew/show/4012 做题背景 在不久的将来,人工智能发展使得人类大量失业,也使得现在的我们做[深海机器人问题]做得想死... ...
- [Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos
题面 sol 设\(f_{i,j}\)表示填了前\(i\)个字母,在\(AC\)自动机上跑到了节点\(j\)的最大得分.因为匹配需要暴跳\(fail\)所以预先把\(fail\)指针上面的匹配数传下来 ...
- 重磅消息-Service Fabric 正式开源
微软的Azure Service Fabric的官方博客在2017.3.24日发布了一篇博客 Service Fabric .NET SDK goes open source ,介绍了社区呼声最高的S ...
- Scala编程快速入门系列(一)
目 录 一.Scala概述 二.Scala数据类型 三.Scala函数 四.Scala集合 五.Scala伴生对象 六.Scala trait 七.Actor 八.隐式转换与隐式参数 九.Sca ...
- 【python学习笔记】7.更加抽象
[python学习笔记]7.更加抽象 类的定义就是执行代码块 在内存保存一个原始实例,可以通过类名来访问 类的实例化,是创建一个原始实例的副本, 并且所有成员变量与原始实例绑定 通过修改实例变量,可以 ...
- this->的作用
参考:https://www.zhihu.com/question/23324143 1.来源: 当年没有C++编译器,只能通过C++转成C语言才编译.而C++中的class就被翻译C语言的struc ...
- Unity性能优化的N种武器
贴图: l 控制贴图大小,尽量不要超过 1024 x1024: l 尽量使用2的n次幂大小的贴图,否则GfxDriver里会有2份贴图: l 尽量使用压缩格式减小贴图大小: l 若干种贴图合并 ...