• HashMap


    一、预备知识

      1.HashMap是Map的常用子类

      java.util.HashMap<k,v>集合 implements Map<k,v>接口

      2.HashMap集合特点

      HashMap集合特点

      HashMap集合底层是哈希表,查询速度特别快

      jdk1.7:数组+单向链表

      jdk1.8:数组+单向链表/红黑树(链表长度超过8,数组达到64)

      

      3.HashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致

    二、HashMap的底层实现原理

      HashMap是Java中的最频繁的一种数据结构

      

      HashMap

      底层是一个hash表(数组+链表),这种结构集合了数组和链表的好处。在jdk1.7中,只是单纯的数组+链表的结构,但是如果散列表中的hash碰撞过多时,会造成效率的降低,所以在JDK1.8中对这种情况进行了控制,当一个hash值上的链表长度大于8时,该节点上的数据就不再以链表进行存储,而是转成了一个红黑树

      HashMap基于Hash算法实现的

        1、当我们往HashMap中put元素时,利用key的hashCode重新hash计算当前对象的元素在数组中的下标

        2、存储时,如果出现hash值相同的key,此时有两种情况。

          1)如果key相同,则覆盖原始值

          2)如果key不同(出现冲突),则将当前的key-value放入链表中

        3、获取时,直接找到hash值对应的下标,再进一步判断key是否相同,从而找到对应值。

        4、理解以上过程就应当了解了HashMap解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。

    四、HashMap的put与get

      put方法

      key的hashcode经过高低位异或后的值,然后(table.legth - 1)& hash得到槽位下标

      此时有4种情况

        1.当槽位(slot)为空,key和value包装为一个node对象,直接存储占用一个solt

        2.槽位不为空,判断key是否一样,一样则进行value替换;否则为hash冲突,存入链表中

        3.已经链化,和2过程相同,比较存入链表但是判断是否达到了树化的扩容阈值标准

        4.红黑树的写入操作

      

      get方法

      拿到key算出对应索引

        1.根据拿到的索引,映射到对应的hash桶,判断该元素是不是头节点,如果是则直接拿到

        2.如果不是头一个节点,用do while循环遍历链表,链表都是next指向下一次拿元素

        3.如果是红黑树,由于添加时保证树有序,则利用折半法遍历红黑树

    hash冲突:

      当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了,这就是所谓的哈希冲突,也叫哈希碰撞

      解决方案:开放定址法(找下一个),再散列法,链地址法(HashMap用的)

  • 相关阅读:
    hdu-5492 Find a path(dp)
    hdu-5493 Queue(二分+树状数组)
    bzoj-2243 2243: [SDOI2011]染色(树链剖分)
    codeforces 724
    codeforces 422A A. Borya and Hanabi(暴力)
    codeforces 442C C. Artem and Array(贪心)
    codeforces 442B B. Andrey and Problem(贪心)
    hdu-5918 Sequence I(kmp)
    poj-3739. Special Squares(二维前缀和)
    hdu-5927 Auxiliary Set(树形dp)
  • 原文地址:https://www.cnblogs.com/xunzf0402/p/16201259.html
Copyright © 2020-2023  润新知