当我们创建HashMap时,底层到底做了什么?
jdk1.7中的底层实现过程(底层基于数组+链表)
在我们new HashMap()时,底层创建了默认长度为16的一维数组Entry[ ] table。当我们调用map.put(key1,value1)方法向HashMap里添加数据的时候:
首先,调用key1所在类的hashCode()计算key1的哈希值,通过key1的hash值与数组的最大索引进行位运算以后,得到了在 Entry数组中的存放位置:
如果此位置上的数据为空,此时的key1-value1添加成功。
如果此位置上的数据不为空(意味着此位置已经存在一个或多个数据),比较key1和已经存在的一个或多个数据的哈希值:
如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。
如果key1的哈希值与已经存在的数据的某一个数据的哈希值相同,继续比较:调用key1所在类的equals()方法:
如果equals()返回false,此时key1-value1添加成功;
如果equals()返回true,使用value1替换value2。
需要注意的是,若原来位置已有数据,则此时key1-value1和原来的数据以链表的方式存储。
在不断的添加过程中,会涉及到扩容问题,当数组容量大于数组现有长度乘以加载因子(如16*0.75,默认的加载因子为0.75)的时候,就会进行数组扩容,以减少哈希冲突(哈希冲突是指哈希函数算出来的地址被别的元素占用了),提高查询效率。默认的扩容方式,扩容为原来容量的2倍,并将原有的数据复制过来。

jdk1.8的底层实现过程(底层基于数组+链表+红黑树)
jdk1.8与jdk1.7中底层的创建过程相似,但有不同,首先,new HashMap()底层没有创建出一个长度为16的数组,在调用put()方法时,判断数组是否存在,如果不存在创建长度为16的Node[ ]数组。接下来的过程与jdk1.7相似。最后,当某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储。
在jdk1.7中,即使在“数组容量大于数组现有长度乘以加载因子”时扩容,也不可避免地会有哈希冲突存在,因此,在jdk1.8中引入红黑树是为了进一步减少哈希冲突,提高查询效率。
红黑树是一种自平衡的二叉查找树,是一种数据结构,典型的用途是实现关联数组。根节点必须是黑色,其他每个节点要么是红色,要么是黑色。
结论:HashMap键是不能重复的,去除重复的条件是依赖键的hashCode方法和equals方法,如果键是自己的对象类型,必须要重写hashCode方法和equals方法,否则,不能去除重复的键。

当我们创建HashMap时,底层到底做了什么?的更多相关文章
- 阿里巴巴Java开发手册建议创建HashMap时设置初始化容量,但是多少合适呢?
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生. 关于HashMap,很多人都对他有一些基本的了解,比如他和hashtab ...
- Django创建项目时应该要做的几件事
终于可以在假期开始学习 Django 啦 !
- SSM-MyBatis-07:Mybatis中SqlSession的insert和delete底层到底做了什么
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先点进去看一下insert方法 用ctrl加鼠标左键点进去看 发现是一个接口SqlSession的方法,没有实 ...
- MySQL实战 | 01-当执行一条 select 语句时,MySQL 到底做了啥?
原文链接:当执行一条 select 语句时,MySQL 到底做了啥? 也许,你也跟我一样,在遇到数据库问题时,总时茫然失措,想重启解决问题,又怕导致数据丢失,更怕重启失败,影响业务. 就算重启成功了, ...
- MySQL数据库详解(一)执行SQL查询语句时,其底层到底经历了什么?
一条SQL查询语句是如何执行的? 前言 大家好,我是WZY,今天我们学习下MySQL的基础框架,看一件事千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题.同样,对于MyS ...
- AFNetworking到底做了什么?(二)
接着上一篇的内容往下讲,如果没看过上一篇内容可以点这: AFNetworking到底做了什么? 之前我们讲到NSUrlSession代理这一块: 代理8: /* task完成之后的回调,成功和失败 ...
- HashMap 和 HashTable 到底哪不同 ?
HashMap 和 HashTable 到底哪不同 ? 2017/05/29 | 分类: 基础技术 | 1 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 ...
- HashMap的底层原理(jdk1.7.0_79)
前言 在Java中我们最常用的集合类毫无疑问就是Map,其中HashMap作为Map最重要的实现类在我们代码中出现的评率也是很高的. 我们对HashMap最常用的操作就是put和get了,那么你知道它 ...
- HashMap的底层原理 cr:csdn:zhangshixi
1. HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变 ...
随机推荐
- MethodHandle(方法句柄)系列之二:方法句柄的简单使用
二话不说,上代码 /** * * @author LiuYeFeng<897908343@qq.com> * @date 2015年4月8日 下午10:41:13 * @CopyRigh ...
- Entity FrameWork 实现分页
SQl语句进行分页 SQL语句进行分页主要是应用Entity FrameWork的SqlQuery()传入SQL语句进行查询时分页. 效果展示. 页面代码展示,显示是用Repeater控件进行动态显示 ...
- Java实现 LeetCode 704 二分查找(二分法)
704. 二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1. 示例 1 ...
- Java实现 LeetCode 200 岛屿数量
200. 岛屿数量 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. ...
- java代码(9) ---guava之Lists、Maps
guava之Lists.Maps 谷歌提供了guava包里面有很多的工具类,Lists和Maps集合工具,集合操作做了些优化提升 一.概述 1.静态工厂方法 (1)Guava提供了能够推断泛型的静态 ...
- 深入理解Java的动态编译
前提 笔者很久之前就有个想法:参考现有的主流ORM框架的设计,造一个ORM轮子,在基本不改变使用体验的前提下把框架依赖的大量的反射设计去掉,这些反射API构筑的组件使用动态编译加载的实例去替代,从而可 ...
- 如何在交互式环境中执行Python程序
相信接触过Python的小伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Pyth ...
- 00-01.Kali Linux 2020.1修改root用户密码
安装Kali Linux 2020.1系统后,需要使用root用户权限安装软件. 由于VMWare版本的root用户默认密码未知,所以需要在单用户模式下重新设置root用户密码.操作步骤如下: 启动K ...
- JS input输入框字数超出长度显示省略号.....
样式添加: overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
- statsmodels中方差分析表结果解析
引言 通常我们在对多个变量进行统计分析的时候,结果的汇总和整理需要耗费大量的时间和精力,稍有不慎还有可能出现错误.因此在对多个变量统计分析的时候,使用自动化的脚本对结果进行整理和汇总就十分的方便了. ...