update hashmap

This commit is contained in:
ranwenjie
2021-07-14 00:59:09 +08:00
parent 0824018756
commit 8c9fc66754
+36 -3
View File
@@ -98,6 +98,23 @@ final Node<K,V> getNode(int hash, Object key) {
```
```
//计算hash值
//这是一个神奇的函数,用了很多的异或,移位等运算,对key的hashcode进一步进行计算以及二进制位的调整等来保证最终获取的存储位置尽量分布均匀
final int hash(Object k) {
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
```
### put(key, value) 方法
@@ -166,6 +183,9 @@ static int indexFor(int h, int length) {
## Hash冲突
HashMap是怎么处理hash碰撞的?
@@ -284,7 +304,7 @@ final Node<K,V>[] resize() {
不需要,但是需要重新调整桶的位置 `newTab[e.hash & (newCap - 1)] = e;`
* 扩容时避免rehash的优化;
* 扩容时避免rehash的优化 : cap 为 2 的次幂,rehash也是 cap * 2 , 这样可以 `e.hash & (newCap - 1)` 计算时,有较少的 key 产生移动,hash值 高位 1 的 才需要移动
@@ -295,12 +315,14 @@ final Node<K,V>[] resize() {
### JDK7 和 8 HashMap 有什么区别?
* JDK8 实现引入红黑树,优化链表过长的查询效率
* 1.7 采用头插法,1.8采用尾插法
* 1.7 采用头插法,1.8采用尾插法; 解决多线程中出出现链表成环的问题 ; (hashmap本来就是非线程安全的,为啥要在多线程中使用hashmap)
### 链表上使用的头插还是尾插方式?
1.7 采用头插法,1.8采用尾插法; 解决多线程中出出现链表成环的问题
### 多线程下死循环问题
@@ -327,7 +349,6 @@ for (int i = 0; i < 1000; i++) {
### hashmap的数组长度为什么要保证是2的幂?
@@ -353,9 +374,21 @@ length 保持为 2 的幂, 那么length-1就会变成一个mask, 它会将hash
### 重写equals方法需同时重写hashCode方法
```
public static void main(String []args){
HashMap<Person,String> map = new HashMap<Person, String>();
Person person = new Person(1234,"乔峰");
//put到hashmap中去
map.put(person,"天龙八部");
//get取出,从逻辑上讲应该能输出“天龙八部”
System.out.println("结果:"+map.get(new Person(1234,"萧峰")));
}
```
hashCode()的默认行为是对堆上的对象产生独特值。因此 map.get(object) 的时候,不同的 object 的hashcode 不一样,自然结果就为null