-
HashMap--小笔记
一、Hash Map在日常开发中是常有用到的,面试也几乎每次必问,详细的HashMap讲解还需查看专业博客,或查看源码,在此只是记录日常开发遇到的问题和记录使用;
1、HashMap的底层:
我们都知道JDK8的Hash Map的底层是数组+链表+红黑树;那么,数字,链表,红黑树到底是怎么用的呢?
当通过 put(key,value),传入一个新的键值对时,底层通过用 新增的 key 算出对应的 hash 值,再用这个 hash 值与数组长度求模(数组默认长度为16)
求得的结果即为该新键值对存放在数组对应的数组索引;
由于通过key算出的hash值可能相同,或者hash值和数组长度求模后值相同,则表示会有多个键值对存放在数组的同一个索引里面,此时就要用到链表结构,如下图:
当使用 get(key)去获取键值对时,也是先通过算Key的hash值,从而得到该key在数组对应的索引值,
但是当该索引值下有多个通过链表存储的键值对时,便需要遍历该链表里面的所有key,直到找到与传入的key相符的值
HashMap的key唯一,可以为null,但只能有一个为null,且如果存在为null的key一定为数组的开头处
当存入相同key的键值对,后者回覆盖前者的值
大家都知道,链表方便插入和删除数据,但查询相当慢的,因此,在JDK8后,引入了红黑树的数据结构
红黑树数据结构具体实现自行去查找,有点长
链表长度超过阈值(8)时,将链表转换为红黑树
2、面试常问
2.1、HashMap和HashTable的区别:
HashMap线程不安全,HashTable线程安全(但为了线程安全也不会用这个,一般使用ConcurrentHashMap),
HashMap可以允许key为null,HashTable不允许
2.2、使用HashMap需要注意什么:
HashMap的扩容是非常耗时间的,每次扩容为扩容前的两倍,初始长度为16,如果大概知道所需长度的话,可以初始化长度,就不需要频繁扩容了
原文:https://www.cnblogs.com/Elaborate/p/14111561.html