HashMap的理解
Hashmap的实现原理
默认它是存放了16个链表头的数组,存储数据的时候key先生成hashcode,根据hashcode把数据存放到相应链表中,那么是如何确定存放到哪个链表中的呢?采用hashcode%len(len是数组长度)。注意这个模数据取余,余数相同的放在同一个桶中的思想用在很多地方。然后hashmap有个静态内部类entry,可以说是hashmap存储数据的基础bean,属性包括key、value、next等,多个entry组成一个链表,有个数组table[],其中存储各个链表的初始节点,这就是hashMap的实现原型,最开始这个数组的长度就是16。
Hashmap存数据
通过key得到hashcode,hashcode对数组table[]长度取余放到相应的链表中。注意,新的键值对将放在链表的头部,放入同一个桶中的新的entry的next将会指向之前的链表头部的entry。为什么不放到尾部呢?很简单,对于一个有长度的链表,当有一个新的entry到来的时候,放到链表的尾部是需要从头部一直找到尾部的,有消耗无收益。
HashMap取数据
取数据的时候是根据hashcode取模直接在table[]中找到相应的链表,然后遍历链表取到value。
一定要注意的
一致性:在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数。
我们知道Map的key在存取数据时候,key需要经历两个过程:1、hashcode取模找链表。2、遍历链表中的entry并与entry的key进行equal比较,来寻找目标value。那么hashcode和equal方法就起了非常重要的作用。
这里分两个情况来说:
1、key为基础数据类型或常用的对象(如String)。这时候值相同的key一定是相同的hashcode,并且equal进行比较的时候,比较的就是值,那么这种情况下HashMap正常使用。
2、key为对象。Object中的equal只是简单的判断是不是同一个实例,比较的是两个对象之间的内存地址是否相同;Object的hashcode方法为默认的内存地址。而很多时候我们使用Map要求的key是逻辑上相同即可而不是要求一定要同一个对象,这就意味着相同值的不同对象会有不同的内存地址。那么使用Map存取的时候,<A对象,value>存入Map,此时B对象和A对象逻辑相等,我们希望拿B对象也能取出value,但是B对象和A对象不是同一对象,于是在hashcode过程中,不同的hashcode值导致去不到目标链表,取值为null;即使假设hashcode值不同但是取模之后也到了目标链表中(几率小),进行key的equal比较时,由于是不同对象,B依然无法取到value,取值为null。所以key为对象的情况下,我们需要重写hashcode方法和equal方法,达成逻辑相同则hashcode相同、equal比较也相同。也应该明白,String也为对象,但是hashcode和equals方法官方已经帮我们重写过了,所以可以直接用,而使用其他对象作为key的时候,这个过程就需要我们自己来完成。
HashMap的理解的更多相关文章
- 关于hashmap的理解
首先分析第一个比较重要的方法 put 方法,源码如下 public V put(K key, V value) { if (key == null) return putForNullKey(valu ...
- 关于java集合类HashMap的理解
一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap ...
- 对HashMap的理解(三):ConcurrentHashMap
HashMap不是线程安全的.在并发插入元素的时候,有可能出现环链表,让下一次读操作出现死循环.避免HashMap的线程安全问题有很多方法,比如改用HashTable或Collections.sync ...
- 【大厂面试08期】谈一谈你对HashMap的理解?
摘要 HashMap的原理也是大厂面试中经常会涉及的问题,同时也是工作中常用到的Java容器,本文主要通过对以下问题进行分析讲解,来帮助大家理解HashMap的原理. 1.HashMap添加一个键值对 ...
- hashMap 深入理解
1.java 的hashMap 是通过 链地址 法来解决 hash冲突的 2.初始时是一个empty table, 第一次添加数据时检查到时空数组就会 生成指定容量的数组,也就是 在第一次使用时才初始 ...
- HashMap简单理解
1. hashmap基于哈希表的map接口实现,此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable ...
- (惊艳)hashmap的理解(映射)
第一: hashmap在内存中是长这样的,数组+链表的形式 // HashMap采用链表法解决冲突,每一个Entry本质上是一个单向链表 transient Entry[] table; 第二: p ...
- 对HashMap的理解(一):HashMap的实现
一.HashMap介绍 1. 定义HashMap实现了Map接口,继承AbstractMap类.其中Map接口定义了键映射到值的规则,而AbstractMap类提供 Map 接口的骨干实现,以最大限度 ...
- 对HashMap的理解(二):高并发下的HashMap
在分析hashmap高并发场景之前,我们要先搞清楚ReHash这个概念.ReHash是HashMap在扩容时的一个步骤.HashMap的容量是有限的.当经过多次元素插入,使得HashMap达到一定饱和 ...
- 对java中hashmap深入理解
1.HashMap的结构是怎样的? 二维结构,第一维是数组,第二维是链表 2.Get方法的流程是怎样的? 先调用Key的hashcode方法拿到对象的hash值,然后用hash值对第一维数组的长度进行 ...
随机推荐
- 用ajax获取后端数据,显示在前端,实现了基本计算器功能
下午在看视频的时候,遇到一个问题:如何把后端 print_r或echo的数据显示在前端.百度了一下,说是用ajax,想着前一阵子学习了ajax,并且最近也想做一个计算器,于是就自己钻起来了. 计算器的 ...
- 两年银行经验的阿里、头条社招面经分享(已拿offer)
lz是非科班自学的java,毕业后进入卡中心,现在是2年开发经验.20年年初先后面了头条.拼多多和阿里(淘宝和支付宝),并成功拿到阿里和头条两家的offer. 面试前我主要是在牛客网看大家的面经进 ...
- CPF 入门教程 - 绘图(四)
CPF NetCore跨平台UI框架,增加了Vlc支持跨平台播放视频. 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) CPF 入门教程 - 样式和动画(三) CPF ...
- OpenCV图像处理学习笔记-Day1
OpenCV图像处理学习笔记-Day1 目录 OpenCV图像处理学习笔记-Day1 第1课:图像读入.显示和保存 1. 读入图像 2. 显示图像 3. 保存图像 第2课:图像处理入门基础 1. 基本 ...
- # 初体验之腾讯位置服务彩云天气开发者api
初体验 最近接触到了boxjs,看到了里面一个比较有意思的彩云天气的脚本,由于自己本身就是彩云天气pro的用户,日常使用过程中感觉到彩云的降雨提醒还是挺方便的,于是就准备开始使用这个天气的脚本. 脚本 ...
- VS2013 c++ 生成和调用DLL动态链接库(.def 方法已验证OK)
转载:https://blog.csdn.net/zhunianguo/article/details/52294339 .def 方法 创建动态库方法: 创建动态库是生成 .dll .lib 两个个 ...
- c++中的GetModuleFileName函数的用法以及作用
参考: 1. http://blog.sina.com.cn/s/blog_b078a1cb0101fw48.html 2. https://www.cnblogs.com/Satu/p/820393 ...
- IDEA2020.2的破解
第一种方式:http://code.39sd.cn/ 直接获取二维码: 第二种:下载破解工具(本方法只是提供个人学习使用) 1.下载2020.2的idea 链接:https://pan.baidu.c ...
- LiteOS-任务篇-源码分析-系统启动函数
目录 前言 链接 参考 开启调度 LOS_Start 函数源码 osTickStart 函数源码 LOS_StartToRun 函数源码 前言 20201009 移植好内核后,开始实战内核. 源码分析 ...
- js 基础概念
一 执行上下文 和 执行上下文栈 执行上下文:一段javascript代码执行前的准备工作 问题一:js引擎遇到怎样一段代码才会做"准备工作呢"? 可执行代码类型:全局代码.函数代 ...