您好、欢迎来到现金彩票网!
当前位置:秒速牛牛投注 > 桶链算法 >

Java中HashMap底层实现原理的源码分析 。

发布时间:2019-09-12 18:54 来源:未知 编辑:admin

  这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JDK1.6.JDK1.7的。现在我来分析一哈最新的JDK1.8的HashMap及性能优化。

  在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

  首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,这样大大提高了查找的效率。

  当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中

  加载因子(默认0.75):为什么需要使用加载因子,为什么需要扩容呢?因为如果填充比很大,说明利用的空间很多,如果一直不进行扩容的话,链表就会越来越长,这样查找的效率很低,因为链表的长度很大(当然最新版本使用了红黑树后会改进很多),扩容之后,将原来链表数组的每一个链表分成奇偶两个子链表分别挂在新链表数组的散列位置,这样就减少了每个链表的长度,增加查找效率

  HashMap本来是以空间换时间,所以填充比没必要太大。但是填充比太小又会导致空间浪费。如果关注内存,填充比可以稍大,如果主要关注查找性能,填充比可以稍小。

  HashMap的构造方法有4种,主要涉及到的参数有,指定初始容量,指定填充比和用来初始化的Map。

  判断键值对数组tab[]是否为空或为null,否则以默认大小resize();

  根据键值key计算hash值得到插入的数组索引i,如果tab[i]==null,直接新建节点添加,否则转入3

  判断当前数组中处理hash冲突的方式为链表还是红黑树(check第一个节点类型即可),分别处理

  构造hash表时,如果不指明初始大小,默认大小为16(即Node数组大小16),如果Node[]数组中的元素达到(填充比*Node.length)重新调整HashMap大小 变为原来2倍大小,扩容很耗时

  在java jdk8中对HashMap的源码进行了优化,在jdk7中,HashMap处理“碰撞”的时候,都是采用链表来存储,当碰撞的结点很多时,查询时间是O(n)。

  在jdk8中,HashMap处理“碰撞”增加了红黑树这种数据结构,当碰撞结点较少时,采用链表存储,当较大时(8个),采用红黑树(特点是查询时间是O(logn))存储(有一个阀值控制,大于阀值(8个),将链表存储转换成红黑树存储)

  你可能还知道哈希碰撞会对hashMap的性能带来灾难性的影响。如果多个hashCode()的值落到同一个桶内的时候,这些值是存储到一个链表中的。最坏的情况下,所有的key都映射到同一个桶中,这样hashmap就退化成了一个链表——查找时间从O(1)到O(n)。

  随着HashMap的大小的增长,get()方法的开销也越来越大。由于所有的记录都在同一个桶里的超长链表内,平均查询一条记录就需要遍历一半的列表。

  如果某个桶中的记录过大的话(当前是TREEIFY_THRESHOLD = 8),HashMap会动态的使用一个专门的treemap实现来替换掉它。这样做的结果会更好,是O(logn),而不是糟糕的O(n)。

  它是如何工作的?前面产生冲突的那些KEY对应的记录只是简单的追加到一个链表后面,这些记录只能通过遍历来进行查找。但是超过这个阈值后HashMap开始将列表升级成一个二叉树,使用哈希值作为树的分支变量,如果两个哈希值不等,但指向同一个桶的话,较大的那个会插入到右子树里。如果哈希值相等,HashMap希望key值最好是实现了Comparable接口的,这样它可以按照顺序来进行插入。这对HashMap的key来说并不是必须的,不过如果实现了当然最好。如果没有实现这个接口,在出现严重的哈希碰撞的时候,你就并别指望能获得性能提升了。

  JAVA里面有HashMap、HashTable、HashSet三种常用的Hash集合,由于经常性的使用,所以想了解一下三种集合的底层实现以及区别,在这里进行总结:一:HashMap和HashTabl...博文来自:你好,我们在哪里见过啊!

  最近有点空余时间,在项目中也经常遇到集合相关的代码,今天利用时间对集合框架中,常用的几个集合进行梳理,首先对hashmap进行梳理,好对其中的概念,和使用技巧进行增强。 1、hashmap的继承体系查...博文来自:Professional

  底层数据结构:链表加数组,数组大小为16,扩容因子为0.75,当数组存储判断为12时,则数组扩容为原来的两倍。若链表节点数超过八个则转化为红黑树。数组做扩容方式为:数据复制到新的数组,然后删除原数组。...博文来自:在那的博客

  作者:清浅池塘链接:来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。公众号:saysayJava...博文来自:心神沫沫的收藏

  最近一直会更新Java软件工程师面试干货。这些知识点得以重视,熟练掌握好,面试一定能够脱颖而出!不管是视频版本还是图文版本,牛耳教育BAT面试题精选解析系列都会持续更新,感谢关注。Java的集合类是一...博文来自:weixin_43952295的博客

  清浅池塘知乎专栏《Java那些事儿》唯一作者,努力打造最好的初学者专栏,关注我能收到专栏推送209人赞了该文章修改记录:2017年8月17日12:00调整了本文顺序,新增小结。本来想先在专栏里简单的说...博文来自:chang_ge的博客

  用过HashMap吗?什么是HashMap?HashMap实现了Map接口,Map接口对键值对进行映射。Map接口的两个基本实现是HashMap和TreeMap。TreeMap保证了对象的排列次序,而...博文来自:雨季会来吗

  1.hash算法的原理散列表(Hashtable,也叫哈希表),是依据关键码值(Keyvalue)而直接进行訪问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来訪问记录,以加快查找的速度。这...博文来自:fxkcsdn的博客

  HaspMap的简述:数据结构:采用hash表的实现结构,然后采用链地址法处理冲突。特点:1、HaspMap继承了AbstractMap类,实现了Map接口。2、HaspMap是线程不安全的,是非同步...博文来自:weixin_39628726的博客

  一、概要       在JDK1.8之前,HashMap采用桶+链表实现,本质就是采用数组+单向链表组合型的数据结构。它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。HashM...博文来自:cb_lcl的博客

  HashMap的实现原理及部分源码分析​Java8拥有增强的Map集合,Map是用来保存具有映射关系的数据。Map接口提供了大量的实现类,典型的实现有HashMap和Hashtable等。Hasht...博文来自:weixin_42378758的博客

  1.HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很...博文来自:T2080305的博客

  《算法第4版本》3.4散列表知乎-R神:关于hashMap的一些按位与计算的问题?知乎-美团:Java8系列之重新认识HashMap新浪博客-无敌宝贝:取余与位运算1.散列表(哈希表)1.1散列函数h...博文来自:Altsuki的博客

  HashMap原理1.7中如果发生冲突,将元素放到链表头部;1.8中如果发生冲突,将元素放到链表尾部;初始大小为16,当元素超过了初始大小的3/4的时候,就会发生扩容,大小翻一番;1.7需要移动的元素...博文来自:mashaokang1314的博客

  前言        以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是resize,这个会重新将原数组的内容重...博文来自:Chenjay‘s Blog

  HashMap的继承结构图:1.HashMap的底层存储结构HashMap的底层结构是数组元素为链表的动态数组实现的。底层代码实现1.1HashMap里几个比较重要的属性1.默认初始化容量static...博文来自:只会一点Java

  转自: 来源:Linux社区 作者:Linux HashMap其实也是一个线性的数组实现的,所以可以理解...博文来自:素年小事

  HashMap特点及原理分析特点HashMap是java中使用最为频繁的map类型,其读写效率较高,但是因为其是非同步的,即读写等操作都是没有锁保护的,所以在多线程场景下是不安全的,容易出现数据不一致...博文来自:xujing_2017的博客

  总的来说,HashMap就是数组+链表的组合实现,每个数组元素存储一个链表的头结点,本质上来说是哈希表“拉链法”的实现。HashMap的链表元素对应的是一个静态内部类Entry,Entry主要包含ke...博文来自:shenjianzhuang的专栏

  此阶段能掌握java基础语法,面向对象思想,抽象类,接口,异常,集合,IO流,文件处理,多线程,网络编程,eclipse的使用等java基础课程,给刚入门的小白提供直接跨入java领域的时空隧道。

  此阶段能掌握java基础语法,面向对象思想,抽象类,接口,异常,集合,IO流,文件处理,多线程,网络编程,eclipse的使用等java基础课程,给刚入门的小白提供直接跨入java领域的时空隧道。

  1:HashMap的实现原理:HashMap的数据结构是由数组和单链表组成。以键值对(key-value)的形式存储元素,添加元素时首先计算元素key的hash值。博文来自:的博客

  HashMap是通过一个Entry的数组实现的。而Entry的结构有三个属性,key,value,next。如果在c中,我们遇到next想到的必然是指针,其实在java这就是个指针。每次通过hashc...博文来自:Holy_Spirit

  一、HashMap的底层数据结构叙述:(1)实现Map集合;(2)底层数据结构是数组链表结构,数组的初始容量是16,每次扩容的大小是上一次的2倍源码中是capacityamp;amp;amp...博文来自:鹤野云间

  java代码在编译后会变成java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,java中所使用的并发机制依赖于JVM的实现和CPU的指令。volat...博文来自:u的博客

  并发编程底层原理Java程序在执行前会被编译为字节码,字节码文件被加载到JVM中,由JVM来执行字节码文件,最终的执行需要转换为汇编语言在CPU上执行,因此,Java的并发编程底层的实现与JVM的实现...博文来自:retreatweb的博客

  最近听了很多人讲了自己面试的一些题目,阿里、京东(很重视学校)、网易等,发现起来都有一个共同特点,都会面试算法,常见的就是KMP、二叉树、链表、红黑树、B树之类的,当然,大公司非常注重底层实现,也就是...博文来自:时光、疏离了记忆づ童话的博客

  HashMap其实也是用一个线性数组实现的,所以可以理解为其存储数据的容器是一个线性数组。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。1、首先HashMap里面实现一个静态...博文来自:ymzyf2007的专栏

  vivi1087:鸿蒙并不是用于手机,并且看上去应该是一个RTOS,所以之前说的和路人猜测都不对。 RTOS的问题是互不兼容和应用与硬件耦合,同样的系统太多了,一直觉得新涌现的RTOS比适配的广度肯定比不过uC/OS,比可验证的实时性和稳定性比不过vXworks 并且网络通信系统能达到的是低延时,而很难达到可靠延时,所以物联网一定有一个部分是重在交互和软件设计的良好性而非全是比拼实时性。

  m0_45232085:5G与AI是数字经济的标志,而区块链则是数字经济的基础。前者是先进生产力,后者则是与其相造应的生产关系。5G与AI让一切都成为可能,不仅创造出巨大的物质财富,让人类的眼耳鼻舌身这些感觉器官无限延伸,也让人类智慧能够积累,提练和升化。但是,这些都是依赖“大数据”的真实性实现的。同时,受资本的“五毒(造假,欺诈,炒作,权力寻租与流氓无赖)”影响,大数据存在“真假变换”的危机,人类即将脱离“耳听为虚,口说无凭,眼见为实”的时代。甚至现实世界都可能被虚拟世界所混淆与替代。人类要真正迈入命运共同体社会,必须引入区块链这一先进技术,直到将资本决定生产要素由需求决定生产要素配置,将资本市场与劳动力市场送入历史坟墓。5G网络(SA)的SBA架构,SND(软件定制服务)正是引入区块链技术的最佳入口。

http://duchtech.com/tongliansuanfa/514.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有