zoukankan      html  css  js  c++  java
  • hashMap的底层实现

      hashMap 不用多说,大家肯定都用过,今天我就hashMap的底层数据结构跟大家做一个分享。

      hashMap 是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-value的存储位置,我们总是可以通过key快速地存、取value。HashMap实现了Map接口,继承AbstractMap。其中Map接口定义了键映射到值的规则,而AbstractMap类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作。

      hashMap中提供了3个构造方法,分别是:HashMap();HashMap(int initialCapacity);HashMap(int initialCapacity, float loadFactor)。这里面主要涉及到2个参数,分别是:initialCapacity(初始容量,默认为16)和loadFactor(加载因子,默认为0.75),举个例子大家就明白了。比如说我现在新创建一个hashMap,

    Map map = new HashMap<String,Object>(16,0.75F);其中16表示该hashMap在初始化时的最大容量,或者说是哈希表中桶的数量,16*0.75=12表示该hashMap存储键值对的最大数量,
    当map中继续put使键值对的数量大于12时,该map将会进行扩容的操作每次新建一个HashMap时,都会初始化一个table数组。table数组的元素为Entry节点。

    
    
    static class Entry<K,V> implements Map.Entry<K,V> {
            final K key;
            V value;
            Entry<K,V> next;
            int hash;
    }
    

     其中Entry为HashMap的内部类,它包含了键key、值value、下一个节点next,以及hash值,这是非常重要的,正是由于Entry才构成了table数组的项为链表(也就是java通过链地址法解决hashMap的hash冲突问题)。hash在进行put的时候,执行步骤如下: 首先判断key值是否为空,若为空,则调用putForNullKey方法(hashMap是支持key为null的),若不为空,则通过key来计算hash值,int hashCode = key.hashCode();再通过hashCode值计算该value存储在数组中的位置坐标index,计算方法为hashCode%size,size为该数组的长度;如果table数组在该位置处有元素,则通过比较是否存在相同的key,若存在则覆盖原来key的value,否则将该元素保存在链头(最先保存的元素放在链尾)。若table在该处没有元素,则直接保存。

    hashMap在取出键值对的时候步骤大致和上面的差不多,只是在数组上该值存在于一个链表中的时候,要对链表进行遍历,通过equals()方法找到正确的value值。

    补充说明一下:在java8.0以后,hashMap在存储结构上做了一定优化,主要是在链表的长度达到8的时候,会将链表转化成红黑树的方式存储,这是因为链表在长度比较长的时候进行遍历性能不是太好,而改用红黑树的数据结构能大大增加对数据的增删给查的效率,提高hashMap的性能。

    HashMap的底层数组长度总是2的n次方,在构造函数中存在:initialCapacity<<= 1;这样做总是能够保证HashMap的底层数组长度为2的n次方。当length为2的n次方时,h&(length - 1)就相当于对length取模,而且速度比直接取模快得多,这是HashMap在速度上的一个优化。具体原因可以参考博客:https://www.cnblogs.com/dassmeta/p/5338955.html

     

        
  • 相关阅读:
    点击标签,通过jquery.jcarousel动态axaj加载内容,实现跑马灯效果
    FreeSwitch VoiceMail 语音信箱 研究
    FreeSwitch IVR VoiceMail 语音信箱
    微软企业库连接access,web.config相对路径配置
    FreeSWITCH 添加中文语音包
    FreeSwitch通过远程接口返回动态IVR语音菜单
    FreeSwitch注册上了,但拨打电话,提示Rejcted by acl "domians". Falling back to Digest auth
    ACM:密码截获
    c++ ACM:递归实例
    CSS:浏览器兼容性图表
  • 原文地址:https://www.cnblogs.com/gaopengfirst/p/10343055.html
Copyright © 2011-2022 走看看