热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HashMap了解一下

今天跟着Java3y的博客(http:www.zhongfucheng.bitcron.compostshou-jipcduan-wen-zhang-dao-hang

今天跟着Java3y的博客(http://www.zhongfucheng.bitcron.com/post/shou-ji/pcduan-wen-zhang-dao-hang)看了一下map接口以及其下子类的代码,水平有限,看的晕晕乎乎的,有的看不懂的地方暂时跳过了,先把理解的地方记录一下,好记性不如烂笔头头头头头。

依然盗图预警,本博客仅用于记录和学习,如有侵犯,请联系我。

HashMap不走心的介绍

  •  首先就是继承关系:HashMap继承AbstractMap类同时实现Map接口
  • 然后要理解一下hashmap的结构,hashmap底层结构是散列表+红黑树(红黑树的理解可以参考其他的优质博文:https://blog.csdn.net/chen_zhang_yu/article/details/52415077),至于散列表的实现,hashmap是采用数组+链表的方式,其中数组中的每个元素也就是平常说的桶,而使用链表主要是为了解决哈希冲突的问题。(大概结构如下图所示)

  • 下面来看一下HashMap的属性:

  • 然后是HashMap的构造方法,HashMap有四个构造函数,值得注意的是,即使在构造函数中指定了initcapacity,初始后的容量也不一定就是所指定的值。而是会返回一个大于指定值的且最接近的2的整数次幂。

  • put方法,以及put方法调用的putVal方法,在putVal方法中,初始时会调用resize方法初始化,当插入元素后会如果size大于阈值的大小,也需要调用resize方法进行再散列,但是。。e..这个方法目前对我来说看着比较困难,先总览一下,随后再补充吧。

  • get方法和remove方法,两者的逻辑差不多,以get方法为例,get中调用的是getNode方法,getNode方法中首先要保证key的哈希值是在散列表上的,然后看是否在桶上,如果在桶上则直接返回,否则利用链表或者红黑树进行搜索并返回(删除)

hashmap补充

 问题1:hashmap容量为什么是2的幂次

  以下答案摘自(https://blog.csdn.net/dam454450872/article/details/80376661)

  1. 首先length为2的整数次幂的话,h&(length-1)就相当于对length取模,这样便保证了散列的均匀,同时也提升了效率;(参考putVal方法中的使用)
  2. 若length为偶数,则最后一位为0,减去1后,最后一位一定为1,此时与h做位与运算,可能为奇数,也可能为偶数。可以反过来想对比一下,如果length为奇数,减一后最后 一位为0,与h做位与后,最后一位为0,一定为偶数,这样不能保证散列的均匀性

问题2:hashmap什么时候扩容

  以下答案摘自(https://blog.csdn.net/u011328417/article/details/80728571)

  1. 我们都知道hashmap的阈值为容量×装载因子。当元素个数大于阈值时就会触发一次扩容
  2. hashmap中定义了TREEIFY_THRESHOLD默认值为8,即当桶内链表的长度大于8时,为了保证效率,会转化为红黑树结构,但是红黑树是治标不治本的,即只能解决查找效率问题,不能解决冲突问题。另外,hashmap还定义了一个MIN_TREEIFY_CAPACITY默认值为64,当桶中的bin被树化时最小的hash表容量。也就是说为当桶数组元素大于 64,且桶内链表长度大于8时才将桶内链表转化为树形结构(这点反映在由链表向树形转化的方法treeifyBin中)。所以,当桶内链表需要转化为红黑树前会先判断桶数组容量是否超过64,若未超过则先进行桶容量扩容。

  总结如下:

    当哈希表中的容量大于MIN_TREEIFY_CAPACITY时,表中的桶才能进行树形化
    否则桶内元素太多时会扩容,而不是树形化
    为了避免进行扩容、树形化选择的冲突,MIN_TREEIFY_CAPACITY值不能小于 4 * TREEIFY_THRESHOLD

问题三:hashmap的key为空值时怎么处理

hashmap中计算key的hash值时,如果key为空则将其hash值直接赋值为0.

问题四:hashmap和hashtable的区别

1、继承不同,虽然二者都实现了map接口,但hashmap继承abstractmap抽象类,hashtable继承的是Dictionary类

2、Hashtable 中的方法是同步的,而HashMap中的方法是非同步的。

3、Hashtable中,key和value都不允许出现null值。

在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

4、遍历方式不同,虽然二者都可使用Iterator,但hashtable还使用了enumeration的方式。

5、hash值的使用不同,hashtable直接使用hashcode。而hasahmap重新计算hash值

6、初始大小和扩容方式不同。hashmap中hash数组初始大小是16,而且一定是2的倍数。hashtable中hash数组默认大小是11,增加的方式是old*2+1

=========================================================================================================

 ConcurrentHashMap介绍

concurrentHashMap是Java.util.concurrent 包下的方法,它也继承了AbstractMap抽象类,但是实现的是ConcurrentMap接口。

然后是concurrenthashmap中用到的cas算法思想和volatile关键字。以下解释摘自https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484161&idx=1&sn=6f52fb1f714f3ffd2f96a5ee4ebab146&chksm=ebd74200dca0cb16288db11f566cb53cafc580e08fe1c570e0200058e78676f527c014ffef41#rd

cas(compare and swap )是一种无锁算法,他有三个参数

内存值v

旧的预期值A

要修改的新值B

当且仅当v==A时,将v修改为B,否则什么都不做。当多个线程尝试使用cas同时更新一个变量时,只有其中一个线程能更新变量的值,而其他线程都失败,失败的线程不会被挂起,而是被告知在这次竞争中失败,并可以再次尝试。

更多介绍参考:https://www.cnblogs.com/jianzh5/p/6671230.html

cas的缺点:https://blog.csdn.net/v123411739/article/details/79561458

volatile经典总结:volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性。

先将今天的体会总结一下:

1、concurrenthashmap的底层也是红黑树+散列表,这点和hashmap相同

2、concurrenthashmap不允许存null(key和value),hashtable也不允许为null,但hashmap允许为null

3、hashtable是使用sychonized对方法进行同步,效率低下,而concurrenthashmap是通过部分加锁+CAS算法来实现线程安全的。

4、concurrenthashmap重写了Node内部类,通过volatile修饰val和next指针来实现每次获取的都是最新设置的值。

 

转:https://www.cnblogs.com/April1995/p/9550024.html



推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
土豆小妈姐_645
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有