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值对第一维数组的长度进行 ...
随机推荐
- C#开发PACS医学影像处理系统(十八):Dicom使用LUT色彩增强和反色
在医生阅片确诊的过程中,当发线疑似病灶时在灰度显示下有时并不清晰,这时候就需要色彩增强效果来使灰度图像变为彩色图像. LUT可以简单的理解为0-255的颜色映射值,例如:彩虹编码,将其打包成LUT格式 ...
- 如何在 PyPI安装python的软件包?
安装软件包 本节介绍如何安装Python的基本知识.包裹. 需要注意的是,这个上下文中的“包”一词被用作分布(即要安装的一组软件),而不是指包装在Python源代码中导入(即模块的容器).Python ...
- Java Web学习(十二)Tomcat核心
一.引言 其实按道理来说,学习Java web应该在前面的篇幅就写有关tomcat相关的知识点,不过近期看了一些资料,觉得以前仅仅只是知道用tomcat去发布我的项目,一些细节的东西也没有好好总结,这 ...
- vue +signalR 实现服务端到客户端消息发送
承接上一篇 上一篇博客实现是了消息的实时通信,这一篇博客主要讲如何从中心服务内部向客户端发送消息. 先看下最终效果: 在core应用程序里加一个控制器TestController 注入控制器中的IHu ...
- 数据类型-字符串(str)
1.只要是被单引号,双引号,三引号括起来的,都是字符串类型 2.字符串里面元素:单个字母,单个符号,都称之为一个元素 例如:s='hello!' (6个元素) len(数据)统计数据的长度pri ...
- Salesforce LWC学习(二十六) 简单知识总结篇三
首先本篇感谢长源edward老哥的大力帮助. 背景:我们在前端开发的时候,经常会用到输入框,并且对这个输入框设置 required或者其他的验证,当不满足条件时使用自定义的UI或者使用标准的 inpu ...
- 12.深入k8s:kubelet创建pod流程源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 在上一篇中,我们知道在kubelet中,工作核心就是围绕着整个syn ...
- 最精美详尽的 HTTPS 原理图!
来源:r6a.cn/ffJk 作为一个有追求的程序员,了解行业发展趋势和扩充自己的计算机知识储备都是很有必要的,特别是一些计算机基础方面的内容,就比如本篇文章要讲的计算机网络方面的知识.本文将为大 ...
- Centos-查看磁盘分区占用情况-df
df 检查linux系统中磁盘分区占用情况 相关选项 -h 以人类友好读方式显示 -k 以KB为单位输出磁盘分区使用情况 -m 以MB为单位输出磁盘分区使用情况 -a 列出所有文件系统分区情况,包 ...
- sipp3.6对freeswitch进行压力测试
一.安装sipp 1.下载地址: https://github-production-release-asset-2e65be.s3.amazonaws.com/13161657/99df6100-9 ...