HashMap问题总结

问题总结

  1. HashMap的特点
    Map<K,V>,以key–value键值对的形式存储数据。
    key不重复,元素的存储位置由key决定,即可以通过key寻找键值对的位置,从而得到value的值。

  2. HashMap如何计算key–Value结果的存储位置?
    计算key的hashcode,然后对hashcode进行扰动处理,最后和table.length - 1进行按位与处理,得到index(下标)。

  3. 解决哈希冲突的方法
    哈希冲突:对hashcode按table.length-1按位与后的下标值相等。

    1. 链地址法:
      jdk1.7中,采用数组+链表的结构。
      jdk1.8中,当一个链表上的节点大于8个时,改用数组+红黑树的结构。
      因为红黑树的时间复杂度(O(log2N))相比起链表(O(n))要低,查找效率高。
      适用于经常进行插入和删除的情况。
    2. 开放定址法
      1. 线性探测再散列
        冲突发生时,顺序查看表中下一单元,知道找出一个空单元或遍历全表。
      2. 二次探测再散列
        di = 1²,-1²,2²,-2²,…,k²,-k²(k<=m/2)
        冲突发生时,在表的组偶有进行跳跃式探测,比较灵活。
      3. 伪随机探测再散列:建立一个伪随机数生成器,冲突发生时,给定一个随机数做起点。
    3. 再哈希法
      同时构造多个不同的哈希函数。当地一个哈希函数发生冲突时,再计算下一个哈希函数,知道冲突不再产生。这种方法不易产生聚集,但增加了计算时间。
    4. 建立公共溢出区
      将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。当发生冲突的元素意义不大时,可以使用这个方法。
  4. HashMap get方法的时间复杂度
    通过key计算index,再遍历链表。
    时间复杂度近似于O(1),由于可能存在冲突所以不一定能达到O(1)。

  5. 为什么hashcode要进行扰动处理
    h ^= (h >>> 20) ^ (h >>> 12);
    降低hashcode的重复率,降低index的重复率。

  6. 为什么hashmap的容量要保持2的幂次
    在计算table的index下标时,因为模运算的消耗大,效率低,所以进行的是hash & (length - 1)这个按位与算数运算操作。为了适应这个操作,数组长度必须是2的幂次,比如16,hash和1111按位与时,这样可以使下标充分地散列,使添加的元素均匀分布在数组上,减少了hash冲突。如果length是15,hash和1110按位与时,最后一位永远是0,会导致0001,0011,0101,1001,1011,0111,1101这几个位置不能存放元素,空间浪费很大,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了冲突的几率,减慢了查询的效率。
    在这里插入图片描述

  7. 如何判断添加了重复的key

    1. key如果为空, 在以数组0号下标为头节点的链表中查找key为null的节点。
    2. key不为空,则先判断hashcode,哈希值不一样key一定不相同。再判断引用地址,如果一样,key一定是一样的。最后比较key。这样做提高了效率,前两步判断速度快,且可以筛选掉大部分比较。直接对象比较的话速度较慢
if (e.hash == hash && (e.key == key || key.equals(k))) 
  1. 如果自己指定HashMap的初始容量和加载因子,那么容量的大小和加载因子对HashMap有什么影响?
    初始容量:向上取整2的幂次,越小越容易发生哈希冲突。
    加载因子:默认为0.75f。加载因子越小扩容越早,哈希冲突概率越小,空间利用率越小。加载因子越大扩容越晚,哈希冲突概率越大,空间利用率更大。
  2. 为什么HashMap需要扩容
    数据量增多时,哈希冲突增多,链表变长,查找元素的效率降低。因此需要扩容。扩容需要计算每一个节点对应的index,哈希冲突几率降低。
  3. HashMap的使用场景
    HashMap查询效率比较高,并且可以通过key去查询对应value。
    自定义user类(账户,密码,性别。年龄)
    HashMap<String,user>
    map.put(“张三”,user1);
    map.get(“张三”);
  4. HashMap的优缺点
    优点:查询效率高,近似于O(1)。
    缺点:默认初始容量和加载因子下,浪费空间。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值