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时,底层到底做了什么?的更多相关文章

  1. 阿里巴巴Java开发手册建议创建HashMap时设置初始化容量,但是多少合适呢?

    集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生. 关于HashMap,很多人都对他有一些基本的了解,比如他和hashtab ...

  2. Django创建项目时应该要做的几件事

    终于可以在假期开始学习 Django 啦 !

  3. SSM-MyBatis-07:Mybatis中SqlSession的insert和delete底层到底做了什么

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先点进去看一下insert方法 用ctrl加鼠标左键点进去看 发现是一个接口SqlSession的方法,没有实 ...

  4. MySQL实战 | 01-当执行一条 select 语句时,MySQL 到底做了啥?

    原文链接:当执行一条 select 语句时,MySQL 到底做了啥? 也许,你也跟我一样,在遇到数据库问题时,总时茫然失措,想重启解决问题,又怕导致数据丢失,更怕重启失败,影响业务. 就算重启成功了, ...

  5. MySQL数据库详解(一)执行SQL查询语句时,其底层到底经历了什么?

    一条SQL查询语句是如何执行的? 前言 ​ 大家好,我是WZY,今天我们学习下MySQL的基础框架,看一件事千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题.同样,对于MyS ...

  6. AFNetworking到底做了什么?(二)

      接着上一篇的内容往下讲,如果没看过上一篇内容可以点这: AFNetworking到底做了什么? 之前我们讲到NSUrlSession代理这一块: 代理8: /* task完成之后的回调,成功和失败 ...

  7. HashMap 和 HashTable 到底哪不同 ?

    HashMap 和 HashTable 到底哪不同 ? 2017/05/29 | 分类: 基础技术 | 1 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 ...

  8. HashMap的底层原理(jdk1.7.0_79)

    前言 在Java中我们最常用的集合类毫无疑问就是Map,其中HashMap作为Map最重要的实现类在我们代码中出现的评率也是很高的. 我们对HashMap最常用的操作就是put和get了,那么你知道它 ...

  9. HashMap的底层原理 cr:csdn:zhangshixi

    1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变 ...

随机推荐

  1. 快速搭建基于Spring Boot + Spring Security 环境

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.Spring Security 权限管理框架介绍 简介: Spring Security 提供了基于 ...

  2. ASP.NET中IHttpHandler与IHttpModule的区别(带样例说明)

    IHttpModule相对来说,是一个网页的添加 IHttpHandler相对来说,却是网页的替换 先建一个HandlerDemo的类 using System; using System.Colle ...

  3. java实现正六面体染色

    ** 正六面体染色** 正六面体用4种颜色染色. 共有多少种不同的染色样式? 要考虑六面体可以任意旋转.翻转. 参考答案: 240 Burnside引理,正方体涂色问题 (n^6 + 3*n^4 + ...

  4. java实现第六届蓝桥杯打印大X

    打印大X 打印大X 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度. 为了便于比对空格,所有的空白位置都以句点符来代替. 要求输入两个整数m n,表示笔的宽度,X的高度.用 ...

  5. unittest单元测试框架入门及应用

    一.简介 unittest是Python单元测试框架.unittest它支持自动化测试,在测试中使用setup(初始化)和shutdown(关闭销毁)操作,组织测试 用例为套件(批量运行),以及把测试 ...

  6. 点击 button 自动刷新页面

    问题:为什么点击 button 会刷新页面 ? 原因:你代码的写法可能如下图,把 <button> 按钮 写在 <form> </form> 标签里边啦. < ...

  7. 小程序-你不得不知的Promise封装请求

    放在开头 这是一个小程序的轮播图,但是为我们在请求api数据时,将请求wx.request代码封装调用 效果展示 代码篇 页面wxml 这里需要注意的是我们设置swiper和image标签时,有默认属 ...

  8. (一)linux三剑客之grep

    给自己提出以下6个问题,看自己是否真正掌握了grep [1] grep 是什么? [2] grep 有什么作用 ? [4] grep 常用于何处 ? [5] grep 的基本用法 ? [6] grep ...

  9. 构造函数,拷贝构造和赋值运算符调用时机,explicit,

    #include<iostream> #include <stdio.h> using namespace std; class test{ int mvalue; publi ...

  10. PIP 更换国内安装源

    linux: 修改 ~/.pip/pip.conf (没有就创建一个), 内容如下: [global] index-url = https://pypi.tuna.tsinghua.edu.cn/si ...