数据结构与算法Java(五):散列表(哈希表)与HashMap底层实现(面试题)

一、概述

散列表是数组的一种扩展,用的是数组支持随机访问数据的特性,key-value的形式

散列冲突:指不同key,产生了相同的value

解决方法:1)开放寻址法:当散列冲突发生时,重新探测一个空闲的位置,将其插入。一般是在数据量比较小,装载因子小时采用。用装载因子表示空位的多少:散列表的装载因子 = 填入表中的元素个数 / 散列表的长度

  • 线性探测的方式(从当前位置出发,依次往后查找)(如ThreadLocalMap采用)  。存在的问题是当插入的数据越来越多时,空闲位置越来越少,线性探测时极端情况下要遍历整张表,时间复杂度O(n)
  • 二次探测:探测的步长是原来的“二次方”,如hash(key)+0,hash(key)+1^2,hash(key)+2^2
  • 双重散列:使用一组散列函数的方式

           2)链表法(常用,如JDK1.7的HashMap):在散列表中,每个“桶”会对应一条链表,所有的散列值相同的元素都放到相同槽位对应的链表中

 

二、面试题HashMap底层实现

  1. 初始大小:HashMap初始大小是16,可以通过修改默认初始大小,减少动态扩容次数,提高性能;
  2. 装载因子和动态扩容:最大装载因子默认是0.75,当元素个数超过0.75*散列表容量时,自动扩容,每次扩容为原来的2倍
  3. 散列冲突解决方法:在JDK1.8前这种“链表法”是解决HashMap散列冲突的方式,在JDK1.8解决散列冲突的方式改为:当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间)
  4. 散列函数:
int hash(Object key) {

    int h = key.hashCode();

    return (h ^ (h >>> 16)) & (capitity -1); //capicity 表示散列表的大小

}

 

参考资料:极客时间的《数据结构与算法之美》王争

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值