HashMap 1.7工作原理
2019独角兽企业重金招聘Python工程师标准>>>
HashMap
hashmap本质数据加链表。根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面。
************************再强调一点,两个String的hashCode相同并不代表着equals比较时会相等,他们两者之间是没有必然关系************************
看3段重要代码摘要:
public HashMap(int initialCapacity, float loadFactor) {int capacity = 1;while (capacity < initialCapacity)capacity <<= 1;this.loadFactor = loadFactor;threshold = (int)(capacity * loadFactor);table = new Entry[capacity];init(); }
有3个关键参数:
capacity:容量,就是数组大小
loadFactor:比例,用于扩容
threshold:=capacity*loadFactor 最多容纳的Entry数,如果当前元素个数多于这个就要扩容(capacity扩大为原来的2倍)
public V get(Object key) {if (key == null)return getForNullKey();int hash = hash(key.hashCode());for (Entry<K,V> e = table[indexFor(hash, table.length)];e != null;e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k)))return e.value;}return null;}
根据key算hash值,再根据hash值取得数组下标,通过数组下标取出链表,遍历链表用equals取出对应key的value。
public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}
从数组(通过hash值)取得链表头,然后通过equals比较key,如果相同,就覆盖老的值,并返回老的值。(该key在hashmap中已存在)
否则新增一个entry,返回null。新增的元素为链表头,以前相同数组位置的挂在后面。
另外:modCount是为了避免读取一批数据时,在循环读取的过程中发生了修改,就抛异常
if (modCount != expectedModCount)throw new ConcurrentModificationException();
下面看添加一个map元素
void addEntry(int hash, K key, V value, int bucketIndex) {Entry<K,V> e = table[bucketIndex];table[bucketIndex] = new Entry<K,V>(hash, key, value, e);if (size++ >= threshold)resize(2 * table.length);}
新增后,如果发现size大于threshold了,就resize到原来的2倍
void resize(int newCapacity) {Entry[] newTable = new Entry[newCapacity];transfer(newTable);table = newTable;threshold = (int)(newCapacity * loadFactor);}
新建一个数组,并将原来数据转移过去
void transfer(Entry[] newTable) {Entry[] src = table;int newCapacity = newTable.length;for (int j = 0; j < src.length; j++) {Entry<K,V> e = src[j];if (e != null) {src[j] = null;do {Entry<K,V> next = e.next;int i = indexFor(e.hash, newCapacity);e.next = newTable[i];newTable[i] = e;e = next;} while (e != null);}}}
将原来数组中的链表一个个取出,然后遍历链表中每个元素,重新计算index并放入新数组。每个处理的也放链表头。
在取出原来数组链表后,将原来数组置空(为了大数据量复制时更快的被垃圾回收?)
还有两点注意:
static class Entry<K,V> implements Map.Entry<K,V>是hashmap的静态内部类,iterator之类的是内部类,因为不是每个元素都需要持有map的this指针。
HashMap把 transient Entry[] table;等变量置为transient,然后override了readObject和writeObject,自己实现序列化。
转载于:https://my.oschina.net/u/3277156/blog/1802555
HashMap 1.7工作原理相关推荐
- 详解HashMap的内部工作原理
本文将用一个简单的例子来解释下HashMap内部的工作原理.首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的. 我们来看个非常简单的例 ...
- Java HashMap的工作原理 及各种Map区别
2019独角兽企业重金招聘Python工程师标准>>> 一.Java HashMap的工作原理 jdk1.7下HashMap数据结构:数组加链表,链表长度没有8的限制: jdk1.8 ...
- Redis一(缓存的工作原理、redis的介绍、hashmap缓存)
文章目录 一.缓存 二.redis 三.hashmap模拟缓存工作原理 1)首先查看数据库中存储的数据格式 2)连接数据库,利用spring在浏览器中显示 3)测试,运行spring接口 一.缓存 当 ...
- HashMap的工作原理
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
- HashMap的工作原理及其相关的知识点
2019独角兽企业重金招聘Python工程师标准>>> 先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?&quo ...
- HashMap的工作原理--重点----数据结构示意图的理解
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如此 ...
- HashMap的工作原理(一):Hash算法
1.什么是Hash Hash也被称为散列.哈希,对应的英文都是Hash.他们的基本原理都是把任意长度的输入,通过Hash算法变成固定长度的输出.这个映射的规则就是对应的Hash算法,而原始数据映射之后 ...
- 一篇文章看明白 HashMap 工作原理
HashMap 源码分析 简介 HashMap 是 Java 语言中常用的用于存放键值对数据类型的集合类.随着 JDK(Java Developmet Kit)版本的更新,JDK 1.8 对 Hash ...
- 阿里P7级别架构师教你HashMap的工作原理
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
最新文章
- Vs code如何快速生成Verilog例化模板
- Extjs中createDelegate的作用
- 赛门铁克公布Q3财报 亏损68亿美元
- Codevs 3002 石子归并 3(DP四边形不等式优化)
- 印度软件业崛起的奥妙
- HBase错误解决(启动Hbase出现错误的替换,启动hbase shell出现ERROR KeeperErrorCode=NoNode for /hbase/master)
- 吞吐量、响应时间和 CPU 利用率之间的关系
- python把工作簿拆分为工作表_使用Python和Pandas将Excel工作表拆分为单独的工作表...
- 【知识向】——计算机基础知识总结及相关
- 如何用python画太阳花
- SQL/ORACLE_基础英语词汇
- 《后端从入门到熟悉-序言》
- 微信小程序意见反馈的实现
- 2022-2027年中国农村小额贷款行业市场调研及未来发展趋势预测报告
- Java基础案例:查找水仙花数(for循环)详解
- linux配置编译指定库,Linux——dropbear编译安装
- 2023年安徽省工业项目投资导向计划奖励补贴、入库申报类别范围
- ajax回调方法名使用什么事件,ajax的回调函数和匿名函数
- python dataframe去掉索引_python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)...
- Spring Boot 2.X + Shiro 优雅解决 session 跨域问题