什么是hashMap
hashMap是一种集合,是Map的具体实现类。同事是一个用于存储key-value键值对的集合,每一个键值对也叫做Entry。
hashMap解决了什么问题
先上结论:解决了数组的增删慢的问题,解决了链表查询慢的问题。
解释:
在hashMap之前有两大家族。
1:数组
特点:存储区间是连续的,占用内存严重,随机读取效率很高,因为带索引,并且数组是连续的。缺点:插入和删除效率太低,因为插入数据,这个位置后面的数据在内存中要往后移,且大小固定不适合动态扩展。
2:链表
特点:存储区间离散,占用内存宽松,插入删除速度块,扩展灵活。缺点:不能随机查找,每次都是从第一个遍历。
所以:哈希表就因此而诞生了,它实现了查询效率高,插入删除效率也高的功能点。而hashMap就是基于hash表实现的。
hashMap的底层实现原理
hashMap基于hashing(算列法或哈希法)原理,我们通过put()和get()方法存储和获取对象。
put():当我们将键值对传递给put()方法时,他的底层会调用key的hashcode()方法获得hash值,再通过hash算法将hash值转换成数组的下标,用于找到bucket位置来存储entry对象,如果下标位置没有任何元素,那就把当前对象添加到这个位置上,如果说下标对应的位置有元素,那就拿着key和链表上的每个节点的key进行equals,如果有相同的那就覆盖,没有相同的那就将这个新的节点添加到链表的末尾。
get():当我们获取对象时,先通过key的hashCode方法得到哈希值,并通过hash算法转换成数组的下标,并且获取bucket(桶)的位置,如果这个位置上什么都没有那就返回null,如果这个位置上有单向链表,那么就会拿着参数key和链表上的每个节点key比较,返回false那就是null,返回true那就 是我们要的value值。
hashMap和hashTable的的区别
1. hashMap是线程不安全的,hashTable是线程安全的
2. 由于hashTable线程安全 所以效率就比hashMap低
3. hashMap最多只允许一条记录的键为null,允许多条值为null,但是hashTable不可以
4. hashMap的默认初始化容量是16 hashTable是11 前者扩容2倍,后者扩容2倍+1
5. hashMap需要重新计算hash值,而hashTable直接使用对象的hashCode
无聊的知识点:
1.随机增删,查询效率都很高的原因是?
增删是在链表上实现的,而查询只需要扫描部分,不需要全盘扫描
2.为什么说JDK8以后哈希表不仅仅是用单向链表了。
在JDK8以后,如果哈希表单向链表的元素超过8个,那么单向链表这种数据结构就会发生变化成红黑树结构,当红黑树上的节点数量小于6个,会重新把红黑树的结构转换成单向链表结构。目的就是优化查询效率。JDK8重写了resize()方法,将在多线程访问下头插法改为尾插法
3.默认配置
hashMap的默认初始容量是16
默认加载因子:0.75f(当存储的数量 > hashMap的容量 * 负载因子)就会把hashMap原来的容量扩大到原来的二倍。
树化阈值:8(在添加元素时,当一个桶的存储元素的数量>8时,自动转换成红黑树)
链表阈值:6(在删除元素时,当一个桶的存储元素的数量<6时,自动转换成链表)