zoukankan      html  css  js  c++  java
  • HashMap的实现原理

    1.数据结构。

      数据存储中有数组和链表,数组通过数组的下标查询,插入时按顺序插入,所以查询快,插入慢,则链表则相反,两种存储结构的有优点也有缺点。

    hashmap的储存的结构就是吸取这两种数据结构的优点组成的结构————也就是耳熟的哈希表。

          结构大概是数组里每个下标存储链表的头结点,然后每个链表数据区域和下个链表的地址。链表的数据按照key(也就是map的key)的hash值对数组的长度取摸然后存在对应的下标中。 其实hashMap的数据结构是一个线性数组,可以动态决定数组的长度,所有的数据存在hashMap的静态内部类entry里。

      头结点: 这是一个单链表最开始附加的,作用是便于找到开始节点,减少单链表的删除,插入复杂性。

      线性数组: 一个数组的长度可以动态改变。

    2.数据存取实现

       transient Entry[] table; 里面3个重要属性: key,value next。key 和value是我们常用的map的key,value , next用于存在一个下标下的多个值的关系。

      数据存储在这个静态内部类里,当存的时候取 int hash=key.hashCode()值,再对数组去摸,hash%length = index.

      map。.put存的时候: entry[index] = value;

      取得时候  1. index=key.hashCode()%length 2.  value =entry[index];

    map.put的时候 hash值是12 如果数组的长度16取摸是 : 12  key为A

            hash值是28 如果数组的长度16取摸是:   12  key为B  这两个值都存储在下标为12下。 用A.next()就能得到B , 下标只会存储最后一个插入的值。

    当数组到达一定数量之后HashMap 通过设置的数组大小相等时执行addEntry方法里的增加数组的大小,一般是2倍,如果当index的值相同拉长了链表会影响性能,hashmap存储一个因子以一定的规则增加entry的长度。最后一点如果key是null 会优先取。putForNullKey(null) //null总是放在数组的第一个链表中

    map.get的时候:1.  先判断key是否为null  有空就返回null的value值 getForNullKey(); 

             2. e.hash == hash && ((k = e.key) == key || key.equals(k)) 3个条件成立的时候才能取  key的entry key的hash值相等,entry的key相等,entry的equals返回true, 这里就验证了多个值存在一个小标中取值得问题, 虽然都存在一个同一个数组下标下,但是每个key的hashCode的值不相同,然而他们存在链表指针区域通过next属性关联在一起。

    null的存储和取: putForNullKey(null)  getForNullKey();  entry[0] 都对下标0操作。

    3.HashMap 初始化过程 通过

    DEFAULT_INITIAL_CAPACITY = 16 创建一个数组大小为16的entry  通过
    DEFAULT_LOAD_FACTOR = 0.75f; 通过一个临界值16*0.75来扩充数组.
  • 相关阅读:
    Swift入门篇-Hello World
    Swift入门篇-swift简介
    Minecraft 插件 world edit 的cs 命令
    搭建本地MAVEN NEXUS 服务
    MC java 远程调试 plugin 开发
    企业内部从零开始安装docker hadoop 提纲
    javascript 命令方式 测试例子
    ca des key crt scr
    JSF 抽象和实现例子 (函数和属性)
    form 上传 html 代码
  • 原文地址:https://www.cnblogs.com/Seeasunnyday/p/6436368.html
Copyright © 2011-2022 走看看