深入理解HashMap

HashMap

特性

  1. HashMap存储键值对实现快速存取,允许key、value为null。key值不可重复,若key值重复则覆盖。
  2. 非同步,线程不安全。
  3. 底层是hash表,不保证有序(比如插入的顺序)

HashMap的底层原理

基于hashing的原理,jdk8后采用数组+链表+红黑树的数据结构。我们通过put和get存储和获取对象。当我们给put()方法传递键和值时,先对键做一个hashCode()的计算来得到它在bucket数组中的位置来存储Entry对象。当获取对象时,通过get获取到bucket的位置,再通过键对象的equals()方法找到正确的键值对,然后在返回值对象。

存储结构

在这里插入图片描述

  1. 从源码可知,HashMap类中有一个非常重要的字段,就是 Node[] table,即哈希桶数组,明显它是一个Node的数组。源码如下图Node[JDK1.8]
    Node是HashMap的一个内部类,实现了Map.Entry接口,本质是就是一个映射(键值对)
    在这里插入图片描述2. HashMap就是使用哈希表来存储的。哈希表为解决冲突,可以采用开放地址法和链地址法等来解决问题,Java中HashMap采用了链地址法。链地址法,简单来说,就是数组加链表的结合。在每个数组元素上都一个链表结构,当数据被Hash后,得到数组下标,把数据放在对应下标元素的链表上

hashMap中put实现

  1. 计算关于key的hashcode值(与Key.hashCode的高16位做异或运算)
  2. 如果散列表为空时,调用resize()初始化散列表
  3. 如果没有发生碰撞,直接添加元素到散列表中去
  4. 如果发生了碰撞(hashCode值相同),进行三种判断
    4.1) 若key地址相同或者equals后内容相同,则替换旧值
    4.2) 如果是红黑树结构,就调用树的插入方法
    4.3) 链表结构,循环遍历直到链表中某个节点为空,尾插法进行插入,插入之后判断链表个数是否到达变成红黑树的阙值8;也可以遍历到有节点与插入元素的哈希值和内容相同,进行覆盖。(jdk8开始采用尾插入)
  5. 如果桶满了大于阀值(0.75),则resize进行扩容
    网上找了个便于理解的图
    在这里插入图片描述

hashMap中get实现

对key的hashCode进行hashing,与运算计算下标获取bucket位置,如果在桶的首位上就可以找到就直接返回,否则在树中找或者链表中遍历找,如果有hash冲突,则利用equals方法去遍历链表查找节点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值