HashMap详细解析

HashMap详细解析

引入:

package com.audition.hashmap;

import java.util.HashMap;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: 两杯水
 * @Date: 2021/03/03/19:02
 * @Description:
 */
public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        String put = map.put("1", "2");
        System.out.println(put);//Entry<key,value>
        String put1 = map.put("1", "3");
        System.out.println(put1);
        System.out.println(put);

        String put2 = map.put("2", "4");
        System.out.println(put2);
    }
}

new Hash()

数组默认容量为16.

put

1.map的put方法是有返回值的

2.put方法时如何存储数据的?

2.1 HashMap存储数据时依靠key的Hash值进行计算下标的,在往数组中存储时,存储的位置是通过key的Hash值"或"数组的长度(防止数组下标越界),计算的数组位置。

2.2 如果计算的Hash值相同,但key值不相同,就把数据存在在数组位置的链表上,JDK1.7采用的是头插法,JDK1.8采用的是尾插法。

为什么区分了JDK1.8修改为了尾插法?
数据采用尾插法插入链表之后,在我们取数的时候,内部采用的是next属性,比采用头插法的方便。
JDK1.7采用头插法,在数组上挂上链表之后,链表会整体往下移动,比较消耗资源。表现在内存中:就是数组和链表是通过数组记录了链表头结点的引用位置,当采用头插法链表下移的时候。数组中的引用地址就会修改为引用数组新的头结点。

3.1.首选会确定map中数据是否为空,如果为空就初始化数据,得到最大容量.同时根据加载因子,计算出最大被扩容的数量
3.2.循环判断链表值,如果有两个Key值一样,会把旧的key中value返回
3.3.JDK1.7:假如达到最大的数量后,大于或等于最大扩容数量是不一定会扩容的,需要看下数组的其他位置有没有空位,如果有空位,就会放到数组上。JDk1.8此条件废除
3.4.扩容是针对于数组,扩容的原因是链表越来越长了。JDK1.8加红黑树就是为了减低链表长度,降低时间复杂度。
3.5.产生的新数组就把旧数组中的数据转移到自己里面。


总结:

  1. 根据Key计算出对应的hashCode,int hashCode = hash(key);

  2. 根据hashCode得到对应的数组下标Index = hashCode & (table.length - 1);

  3. 根据Key.value.hashcode生成Entry对象,entry = new Entry(key,value,hashCode);

  4. 得到对应的数组下标后,如果table[index]为空,则直接把Entry对象赋值给table[index],table[index]=entry;

  5. 得到对应的数组下标后,如果table[index]不为空,则把Entry对象添加到改位置对应的链表上

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页