1.index 冲突:
底层做二进制运算 产生相同的index (key存放数组的下标位置)
对象不同 但是二进制运算是相同的index h&(length -1) 偶数 发生冲突概率特别大 length-1变为基数
length -1
:来避免冲突
2. hashcode冲突 :
对象不同 但是hashcode值相同 在hashMap中为了确保相同的key 是用equals
底层计算 value生成的hashcode值相同 ,在同一个索引位置, 用链表进行保存(hashcode值相同的元素)
链表
保存来避免冲突
3.index冲突会存在哪些问题?
会导致 值覆盖掉 所以用链表解决。 相同的index 最新的值在最前面 最新的值->next 原来的值
4. 同一个链表存放了 那哪些内容?
index冲突 或 hash冲突
5. hashmap是单向链表
6. 如果hashmap链表长度过长 会存在哪些问题
会导致 查询效率降低 时间复杂度 O(n)
7.hashmap key为空 null时,底层是如何存放?
数组index为0 或 第一个链表
8. jdk1.7的hashmap存在哪些问题?
1.hashmap 线程不安全
2.链表长度过长 查询效率降低
3.底层扩容的时候 可能会存在 死循环
4.jdk7中 hashmap计算hash值非常均摊 减少hash冲突问题 因为链表查询效率非常低
jdk8 hashmap计算hash值非常简单 存在hash冲突的概率比jdk7要大 但是没关系 因为jdk8中hashmap是用红黑树 解决查询效率的问题
9. jdk1.7的hashmap根据key查询时间复杂度多少?
o(1) 容量增大也不影响查询效率
分为2种情况:
1.如果该key没有发生hash冲突的话,可以直接根据key值计算hashcode 再根据hsshcode计算index 直接从数组中查询
2.发生hash冲突 会形成一个链表 查询效率会降低
9. hashmap每次扩容几倍?
2倍
0.75倍是阈值 达到0.75就开始扩容
10. 为什么加载因子是0.75?
11. hashmap是否可以存放自定义类型为key
可以
12. hashmap jdk7在并发情况下 扩容时候 回存在哪些问题?
死循环 jdk8已经解决
扩容的时候 会重新计算index值 (因为table.lenth 变为原来的2倍了)
默认初始容量16
13.数组扩容为原来的2倍:
数组+链表 数组的每一项是链表
e = A
e.next = B
假设计算的 e的索引在newTable是 索引 i = 2
那么 e.next = newTable[2] 让e的next是newTable中原来i=2的元素 形成新的链表
newTable[2] = e 现在 newTable[2]位置上是 e
最新的在最前面
最新的元素 next(指向)新表中该索引 原来的元素
相当于 newTable 中同样index=2 存储的是链表 现在的数据 是inde=2 原来在index=2的数据 成为 index=2位置上 链表的 下一个
至于 e=next 就是 现在e=B 从新执行循环操作