• HashMap系列之底层数据结构


    数据结构的概念

    数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法索引技术有关。

    HashMap的底层数据存储过程

    使用代码:

    public class Demo01 {
        public static void main(String[] args) {
            HashMap<String, Integer> map = new HashMap<>();
            map.put("Kobe", 40);
            map.put("James", 36);
            map.put("Iverson", 45);
            map.put("Jordan", 57);
            map.put("Kobe", 41);
        }
    }
    

    输出结果:

    {Kobe=41, James=36, Jordan=57, Iverson=45}
    

    具体存储过程

    1. 在jdk1.8之前,构造方法中创建一个长度是16的 Entry[] table 用来存储键值对数据的。在jdk1.8以后不是在HashMap的构造方法底层创建数组了,是在第一次调用put方法时创建的数组 Node[] table 用来存储键值对数据。
    2. 根据存储的数据中的key值,利用hashcode方法计算出哈希值,然后结合数组长度采用某种算法计算出向Node数组中存储数据的空间的索引值。若索引位置没有数据,则将数据存储。
    3. 根据上面的代码,如果根据Kobe计算出来的索引值为2,,根据Iverson计算出来的索引值也为2,那么此时数组空间不是null,此时底层会比较Kobe和Iverson的hash值是否一致,如果不一致,则在空间上划出一个结点来存储键值对数据<"Iverson", 45>,这种方式称为拉链法。
    4. 第一个存储的数据是Kobe,第五个存储的数据也是Kobe,根据Kobe计算出来的索引值肯定一样,那么就会直接比较二者哈希值,很明显哈希值一样,这个时候就会发生哈希碰撞,那么底层会调用Kobe所属类 String 中的 equals() 方法比较两个内容是否相等:相等:将后添加的数据的value覆盖之前的value。不相等:继续向下和其他的数据的key进行比较,如果都不相等,则划出一个结点存储数据,如果结点长度即链表长度大于阈值8并且数组长度大于64则将链表变为红黑树。
    5. 随着数据越存越多,就会涉及到数组的扩容问题,当超出数组阈值时,会发生扩容,且扩容为原数组的两倍,并将元素组内容复制到新数组中。

    总结


    说明:

    1.size表示 HashMap中K-V的实时数量 , 注意这个不等于数组的长度 。

    2.threshold( 临界值) =capacity(容量) * loadFactor( 加载因子 )。这个值是当前已占用数组长度的最大值。size超过这个临界值就重新resize(扩容),扩容后的 HashMap 容量是之前容量的两倍 。

  • 相关阅读:
    bzoj 1821: [JSOI2010]Group 部落划分 Group
    codevs 1217 借教室
    洛谷 P2678 跳石头
    洛谷 P1316 丢瓶盖
    洛谷 P2683 小岛
    洛谷 P2431 正妹吃月饼
    loj #6092. 「Codeforces Round #418」恋爱循环
    loj #6091. 「Codeforces Round #418」幻想特快
    loj #6090. 「Codeforces Round #418」尘封思绪
    前端移植说明
  • 原文地址:https://www.cnblogs.com/leiger/p/13255442.html
Copyright © 2020-2023  润新知