美文网首页算法与数据结构
Java中常见的数据结构(二)——HashMap

Java中常见的数据结构(二)——HashMap

作者: vvweilong | 来源:发表于2019-04-13 18:44 被阅读0次

这篇我们看看HashMap的实现
HashMap 由名字可知这是一个用Hash散列表实现的map集合
map集合的特点是 由Key 与 Value 组成的键值对 每个key对应自己的value 使得查找 只要计算key的hash值 就能得到value 的位置 ,而这种随机查找的特性显然是数组的特点 。
第一个我们就看到了

table
这个数组就是map数据实体存放的位置了
还是 增删查 三个方法 首先看 查 get方法
get(key)
getNode(int hash,Object key)
我们看到 getNode() 是实际获取目标对象的方法,传入的参数有两个一个是 hash值 另一个是 key
hash值是通过hash(key)方法计算而来,为什么又传了key进来呢?
散列表有个问题就是碰撞问题,不同的key可能会产生相同的hash值,这就造成了碰撞,为了解决这个问题,在散列表相同位置会有一个链表来存储这些hash值相同的对象,为了在链表中找到目标key对应的值,所以要将key传进来。
这个过程在getNode()方法中很明显。
再看put 方法:
put(key,value)
putVal
为了截图我折叠了一部分代码,首先看看put 的过程
首先我们看到一个 table 数组的判断和resize()方法,看来是对元素的实体集合进行了容量处理,毕竟是数组。
然后我们看到 用hash值 计算对应的数组索引来获取对象,如果为空则创建一个新的结点对象保存到数组中 ,如果不为空
image.png
我们看有三种情况的处理
首先判断了目标位置结点与新加入结点是否为同一个判断方法是 hash值相同,并且key相同
然后判断了当前位置的结点是否是树形结点如果是 则进行树形结点的put操作。
最后是添加到链表尾部的情况。
(结尾执行的afterNodeAccess(e)与afterNodeInsertion(e)都是空实现,在用链表实现的hashmap中有具体的实现操作。)
remove()方法与 put() 方法过程类似,都是通过hash找到数组的索引然后查询链表找到对象 。下面我们看一下resize()方法;
resize()
我们看到 在一般情况下 newCap=oldCap<<1 也就是2倍关系 也就是说正常情况,每次扩容都是 2×oldCap ;
我们还看到两个变量 threshold 与 loadFactor
threshold 的注释说 这个下一次进行resize的容量数值 于是我们在putVal方法中看到这样一句

在Android SDK中还有另一种类似数据 ArrayMap


ArrayMap的类注释

说明ArrayMap是安卓设计的一种更高效利用内存的HashMap数据结构
采用两个数组来实现map结构的Key-Value对应关系,一个存储hashcode 一个存储 key/value pair 对象,还是看一下具体代码 以put方法为切入口
先看第一部分


image.png
这里主要进行的是获取key对应的index值。
indexOf(key,hash)

首先一个二分查找在hash值的数组中查找目标hash 的索引
然后通过索引在mArray中找到对应的key ,返回目标key的索引
最后如果没有找到目标hash值说明是个新的key 则返回一个新key应该放置的index



执行到这部分说明是个新加入的key 和value ,首先要对容量进行扩容检查 ,扩容之后
image.png
将新的key放在mHashes数组的对应位置,将值翻入mArray的对应位置。
我们再来看看 线程安全的HashMap HashTable
put方法
可以看到 是在方法上加了 synchronized 关键字来实现线程同步,其他的功能实现与HashMap类似。
接下来是 concurrent包下的HashMap
ConcurrentHashMap的put 方法
方法前并没有 synchronized 关键字,那是在哪里进行了线程同步呢 ?
image.png

这个f 是在执行第一个else if时进行了赋值 tabAt()也就是key对应散列表的列表表头对他进行了加锁处理。
而remove操作对应的是replaceNode方法


remove流程的线程同步
同样也是在找到key对应的节点后 进行锁处理。

相关文章

  • 数据结构

    Java数据结构 常见的数据结构 HashMap 迭代方式: keyset entryset 比较:keyset比...

  • HashMap剖析

    Java集合:HashMap源码剖析 一、HashMap概述 二、HashMap的数据结构 三、HashMap源码...

  • [Java 8 HashMap 详解系列] 2.HashMap

    [Java 8 HashMap 详解系列] 文章目录 1.HashMap 的存储数据结构 2.HashMap 中...

  • HashMap的简单解析

    在Java中HashMap算是比较常用的集合框架,是Java中比较典型的数据结构。在本文中主要探究HashMap中...

  • 深入了解HashMap的底层原理

    深入了解HashMap的底层原理 各位java开发的同学肯定对HashMap并不陌生,它是一种非常常见的数据结构,...

  • Java集合之HashMap

    转载:https://tech.meituan.com/java-hashmap.html Java为数据结构中的...

  • HashMap&CurrentHashMap

    java7中的hashMap和currentHashMap hashMap 数据结构 数组加链表 寻址方式 将ke...

  • JDK1.8 HashMap源码分析(一)

    HashMap是java开发中常见的一个类,也是面试中经常会被问到的类,诸如: HashMap的底层数据结构是什么...

  • Java容器类框架分析(3)HashMap源码分析

    概述 在分析HashMap的源码之前,先看一下HashMap在数据结构中的位置,常见的数据结构按照逻辑结构跟存储结...

  • 详解HashMap、HashTable、ConcurrentHa

    之前的文章《HashMap源码详解》中我们已经结合Java1.8中HashMap的源码对数据结构、数据存取、数据写...

网友评论

    本文标题:Java中常见的数据结构(二)——HashMap

    本文链接:https://www.haomeiwen.com/subject/micrwqtx.html