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工作原理相关推荐

  1. 详解HashMap的内部工作原理

    本文将用一个简单的例子来解释下HashMap内部的工作原理.首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的. 我们来看个非常简单的例 ...

  2. Java HashMap的工作原理 及各种Map区别

    2019独角兽企业重金招聘Python工程师标准>>> 一.Java HashMap的工作原理 jdk1.7下HashMap数据结构:数组加链表,链表长度没有8的限制: jdk1.8 ...

  3. Redis一(缓存的工作原理、redis的介绍、hashmap缓存)

    文章目录 一.缓存 二.redis 三.hashmap模拟缓存工作原理 1)首先查看数据库中存储的数据格式 2)连接数据库,利用spring在浏览器中显示 3)测试,运行spring接口 一.缓存 当 ...

  4. HashMap的工作原理

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

  5. HashMap的工作原理及其相关的知识点

    2019独角兽企业重金招聘Python工程师标准>>> 先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?&quo ...

  6. HashMap的工作原理--重点----数据结构示意图的理解

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如此 ...

  7. HashMap的工作原理(一):Hash算法

    1.什么是Hash Hash也被称为散列.哈希,对应的英文都是Hash.他们的基本原理都是把任意长度的输入,通过Hash算法变成固定长度的输出.这个映射的规则就是对应的Hash算法,而原始数据映射之后 ...

  8. 一篇文章看明白 HashMap 工作原理

    HashMap 源码分析 简介 HashMap 是 Java 语言中常用的用于存放键值对数据类型的集合类.随着 JDK(Java Developmet Kit)版本的更新,JDK 1.8 对 Hash ...

  9. 阿里P7级别架构师教你HashMap的工作原理

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

最新文章

  1. Vs code如何快速生成Verilog例化模板
  2. Extjs中createDelegate的作用
  3. 赛门铁克公布Q3财报 亏损68亿美元
  4. Codevs 3002 石子归并 3(DP四边形不等式优化)
  5. 印度软件业崛起的奥妙
  6. HBase错误解决(启动Hbase出现错误的替换,启动hbase shell出现ERROR KeeperErrorCode=NoNode for /hbase/master)
  7. 吞吐量、响应时间和 CPU 利用率之间的关系
  8. python把工作簿拆分为工作表_使用Python和Pandas将Excel工作表拆分为单独的工作表...
  9. 【知识向】——计算机基础知识总结及相关
  10. 如何用python画太阳花
  11. SQL/ORACLE_基础英语词汇
  12. 《后端从入门到熟悉-序言》
  13. 微信小程序意见反馈的实现
  14. 2022-2027年中国农村小额贷款行业市场调研及未来发展趋势预测报告
  15. Java基础案例:查找水仙花数(for循环)详解
  16. linux配置编译指定库,Linux——dropbear编译安装
  17. 2023年安徽省工业项目投资导向计划奖励补贴、入库申报类别范围
  18. ajax回调方法名使用什么事件,ajax的回调函数和匿名函数
  19. python dataframe去掉索引_python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)...
  20. Spring Boot 2.X + Shiro 优雅解决 session 跨域问题

热门文章

  1. Java学习笔记22
  2. 创建型模式--原型模式
  3. 创建型模式--工厂方法模式
  4. 用单片机测量流体流速的_曹阳等:钻井用节流阀抗冲蚀性能的实验评价
  5. 跳一跳python源码下载_Python玩跳一跳【简】
  6. HEOI2016/TJOI2016 字符串问题
  7. Cocoapods 私有库
  8. mybatis中(Oracle)关于insert时主键自动加1的使用方法
  9. cnblog写博客还不错嘛
  10. sdcms的一个bug,总是提示,该文件不允许被上传