Java教程

HashMap

本文主要是介绍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用的)

 

这篇关于HashMap的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!