zoukankan      html  css  js  c++  java
  • HashMap实现原理和底层数据结构?

    1 底层数据结构

    数组(主体) + 链表(解决哈希冲突)

    2 实现原理

    HashMap 的主干是一个Entry数组,初始值是一个空数组 {}

    Entry是HashMap的基本组成单元,每一个Entry包含一个 key-value 键值对。 

    HashMap 整体结构   

    Entry源码

    static class Entry<K,V> implements Map.Entry<K,V> {
            final K key;
            V value;
            Entry<K,V> next;//存储指向下一个Entry的引用,单链表结构
            int hash;//对key的hashcode值进行hash运算后得到的值,存储在Entry,避免重复计算
    
            /**
             * Creates new entry.
             */
            Entry(int h, K k, V v, Entry<K,V> n) {
                value = v;
                next = n;
                key = k;
                hash = h;
            }     

    HashMap源码中其他几个重要字段

    //实际存储的key-value键值对的个数
    transient int size;
    //阈值,当table == {}时,该值为初始容量(初始容量默认为16);当table被填充了,也就是为table分配内存空间后,threshold一般为 capacity*loadFactory。HashMap在进行扩容时需要参考threshold,后面会详细谈到
    int threshold;
    //负载因子,代表了table的填充度有多少,默认是0.75
    final float loadFactor;
    //用于快速失败,由于HashMap非线程安全,在对HashMap进行迭代时,如果期间其他线程的参与导致HashMap的结构发生变化了(比如put,remove等操作),需要抛出异常ConcurrentModificationException
    transient int modCount;

    key 到 数组下标的转换

    当发生哈希冲突并且size大于阈值(threshold)的时候,需要进行数组扩容,扩容时,需要新建一个长度为之前数组2倍的新的数组,然后将当前的Entry数组中的元素全部传输过去,扩容后的新数组长度为之前的2倍,所以扩容相对来说是个耗资源的操作。

      参考链接:https://www.cnblogs.com/chengxiao/p/6059914.html        

  • 相关阅读:
    Android学习(九) SharedPreferences
    Android学习(八) 打开Activity
    Android学习(七) Android实现计算器
    Android学习(六) 文本框边框
    Android学习(五) 圆角实现(转)
    Android学习(四) Layout五大布局
    Android学习(三) 自动完成的使用
    SQL Server中的三种物理连接操作
    ASP.NET实现大文件下载
    ASP.NET上传大文件的问题
  • 原文地址:https://www.cnblogs.com/starinbrook/p/9383283.html
Copyright © 2011-2022 走看看