HashMap理解(2018.3.21)

在工作了一段时间之后,上课的时候基础已经忘得七七八八了,今天突然看到群里的朋友问了一些关于HashMap的面试题,也想着自己整理一下对HashMap的一些理解

使用过HashMap么?他有什么用处?

只要学习过Java的同学想必都用过HashMap,HashMap对于日常的工作中可以方便的存储一些我们需要存放的对象,最基础的便是get/put方法,对于HashMap的一些特性,比如HashMap是可以储存null键和null值得,而与之对应的HashTable则不行,HashMap是非线程安全的,因此它的速度会相对来说快一些,HashMap储存的是键值对等等,到此,说明在日常工作中,对HashMap的理解还是比较到位的。

你知道HashMap的工作原理吗?

  • 针对第一个问题,其实HashMap最基础的就是基于Hashing的原理,
  • 当我们给put方法传递<K,V>时,会首先调用hashCode方法对K进行哈希值的计算,得到哈希值后,去bucket中寻找对应的储存地址,并且把<K,V>储存进当前的储存地址。
  • 当调用get方法的时候,同样是寻找相对应的hashCode对应的bucket储存地址,并取出相对应的键值对。

特别要指出的是,当K为null时,HashMap默认是储存在第一个位置当中的。

HashMap的数据结构

HashMap是综合了链表和数组的产物,先来了解一些链表和数组,这两个相对来说是两个极端的储存方式。

  • 数据是有序存放数据的,占用的内存集中,因此有插件简单快速,但是插入和删除的代价大
  • 链表是随机存放的,占用的内存随机,通过节点标识来形成链状结构,因此查询不易,但是插入和删除比较方便

而HashMap在处理hashCode时采用的是数组,而每个数组都相当于是链表的header。因此可以想到,在一定的条件下,HashMap和数组/List一样,是需要扩容的,会有一个reHashing的操作,然后把之前的数据全都存放到新的HashMap中。默认的负载因子是0.75.

当两个对象的hashcode相同时,调用put/get会发生什么

在刚才我们提到过,put时调用hashCode方法会找到bucket中的位置,然后再该位置进行存放,如果两个对象的hashCode相同时,会进行什么样的‘碰撞’
有些同学可能会觉得就是直接覆盖,或者因为hashCode相同,会抛出异常,不进行储存。其实上一段说的数据结构,在这里便产生了结果。在bucket中的某一位置,对应的实际是一个链表结构,因此,put方法只是在其中又加了一节链表而已。

  • 那么问题来了,这个时候我们调用get方法,获取到的其实是一个链表,而不是一个对象,难道只是简单的取最新的一个么?
  • 其实不是的 ,因为在HashMap中不仅是用hashCode做判断,因为我们还会有equals方法,在链表中,我们又会采用equals方法找值相等的,就会得到唯一的一个对象。

在到达了负载因子的情况下,扩容会发生什么问题?

在工作中还是比较容易想到的,就是并发问题,在多线程的情况下,若两个线程都达到了复杂因子,他们同时产生扩容操作,便会产生条件竞争,在扩容时元素的排列顺序便会反序存放,在条件竞争时便会产生死循环。

  • 解决方法:并不应该局限于如何解决这个问题。因为HashMap本身就是非线程安全的,完全可以采用并发包下的CocurrentHashMap

为什么使用String,Integer等等wapper比较合适作为K?

因为在生产环境中,这些是最常用的,并且在这些类中的hashCode和equals方法都经过了重写,并且是属于final的不可变的,因此作为K值可以有效提高查询效率。

我们可以使用CocurrentHashMap来代替Hashtable么?

这就需要看实际的业务场景了,在大多数情况下,我认为是可行的。
这两个类相较于HashMap的区别想必大家都清楚,就是这两个类都是线程安全的,但是两者之间,HashTable的线程安全等级更高一些,但是同样导致了性能的丢失。

  • 具体体现在,当HashTable的大小到达一定的程度时,扩容操作就会显得非常慢,此时该Map是被上锁的,因此导致它的即时性能急剧下降,同时也就意味着,即便两个线程操作不同的数据,也会因整体上锁而需要等待。
  • 而CocurrentHashMap采用了分割的概念,也就是分块治理的,因此不管整体的数据量有多大,只需要扩容部分数据,而其他部分则不会受到影响,同样的,可以理解不同线程操作不同的数据时,可以给不同的区块上锁,相当于在一定程度下允许了同时有多线程操作,有效提升了他的性能。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342