zoukankan      html  css  js  c++  java
  • HashMap-JDK源码阅读

    HashMap 结合数组的快速查询和链表的快速插入等优点实现。

    参数说明:

      table:数组长度。

      size:k-v数量。

      modCount:结构改变标记,主要在并发环境下HashMap发生扩容等结构变化时校验,迭代时如果不及预期则抛出异常ConcurrentModificationException,而不是迭代完后再做校验。

      lodaFactor:加载因子,表示k-v在hashMap的密度。默认0.75,是一个对空间时间的权衡值,需求时间减少,需求空间增加。

      capacity:数组长度,初始值16;

      threshold:resize vlaue

    put操作:

    1. 取得hashCode()。
    2. 高16位异或低16位,计算hash值。
    3. 如果篮子里面值为空hash值未发生碰撞,则直接放到篮子里。
    4. 如果hash值发生碰撞则迭代链表equals key值。
    5. 比较头节点如果相同就替换。
    6. 头节点不相同如果是否是红黑树则putTreeVal。
    7. 如果有key则替换v。
    8. 如果没有key则挂在后面。
    9. 如果链表长度等于大于等于8就把链表转成红黑树。
    10. 如果size大于threshold,扩容为原来的2倍。

    set操作:

    1. 取得hash值
    2. 通过数组查找第一。
    3. 找不到再迭代后面的链表。

    几个精妙的算法:

    tableSizeFor(int cap),计算大于cap的最小的2的平方。从二进制的角度进行无符号右移操作得到最接近大于这个数的0x....11111,然后+1。

    resize(),从二进制的角度,让原值均匀的分布在原位置或者原位置移动原长度的位置(2的幂),扩容后由于长度是原来的两倍,数组下标的hash会增加1位,通过&运算多查看一位hash,如果为0则说明在原位,如果为一说明在原位置移动原数组长度的位置,这就是数组长度用2次幂的好处之一,简直是精妙,省去了重新计算hash的操作,并发在这里会出现死链。

    这只是我对HashMap自己的理解,详细可看:http://www.importnew.com/20386.html  

  • 相关阅读:
    Android与WebView的插件管理机制
    在mac下搭建Apacheserver
    “懒”也要有境地---大部分程序猿都在的地方,再不来就out了。
    codeforces Looksery Cup 2015 H Degenerate Matrix
    HDU 1247 Hat’s Words(字典树变形)
    SICP 习题 (1.38)解题总结
    scikit-learn:4.2. Feature extraction(特征提取,不是特征选择)
    iOS_高效开发之道
    亚马逊2014在线面试第一题
    通过AO连接多个EO并进行使用
  • 原文地址:https://www.cnblogs.com/fastLearn/p/6702113.html
Copyright © 2011-2022 走看看