散列表(哈希表)

一. 简介

  • 散列表也叫哈希表,是存储Key-Value映射的集合。通过哈希函数实现Key和数组下标的转换,通过开放寻址法和链表法解决哈希冲突,且读写操作时间复杂度接近O(1)。

二. 原理

  1. 哈希函数
    散列表是基于数组的,通过哈希函数把Key和数组的下标进行转换。

    哈希函数的实现方式有很多种,以HashMap中的哈希函数为例:每个对象都有属于自己的hashcode(唯一性),而hashcode都是一个整型变量,再由hashcode对数组长度取模运算(index = HashCode(Key) % Array.length),实现Key转换为数组的下标index。

  2. 散列表的读写操作
    (1)写操作(put)
    写操作即插入新的键值对(在JDK中叫做Entry)。

    如调用hashMap.put(“002931”,“小明”)的步骤:
    a. 通过哈希函数,把Key转换为数组下标5;
    b. 若数组下标为5的位置没有元素,就把这个Entry填充到此位置;
    c. 若数组下标为5的位置有元素了(即发生了我们常说的哈希冲突,解决方法有:开放寻址法、链表法),HashMap采用了链表法解决哈希冲突,先判断此链表中是否有了这个Key,如果有了此Key则用新的value值代替旧的value值,如果没有此Key,则将键值对插入到链表头。

    【拓展】解决哈希冲突的两种方法
    开放寻址法:当一个Key通过哈希函数获得对应的数组下标被占用时,寻找下一个空档位置。
    链表法:当一个Key通过哈希函数获得对应的数组下标被占用时,先判断此链表中是否有了这个Key,如果有了此Key则用新的value值代替旧的value值,如果没有此Key,则将键值对插入到链表头。

    (2)读操作(get)
    读操作即通过给定的Key,在散列表中查找对应的值。

    如调用hashMap.get(“002931”)的步骤:
    a. 通过哈希函数,把Key转换为数组下标5;
    b. 找到数组下标为5所对应的元素,如果这个元素的Key是002931,就找到了;若Key不是002931,顺着链表往下找,找到匹配的节点即可。

    (3)扩容 (resize)
    a. 影响扩容的因素:
    Capacity:即HashMap的当前长度;
    LoadFactor:即HashMap的负载因子,默认是0.75f。

    b. 衡量扩容的条件:HashMap.Size >= Capacity x LoadFactor

    c. 扩容的步骤
    扩容:创建一个新的Entry空数组,长度是原来数组的2倍;
    重新Hash:遍历原Entry数组,把所有的Entry重新Hash到新数组中,其目的就是将原来的Entry尽可能均匀的分配。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值