深入浅出hashmap原理

属性相关的问题

  • 默认容量为什么是16?
  1. HashMap作为一种数据结构,元素在put的过程中需要进行hash运算,目的是计算出该元素存放在hashMap中的具体位置。hash运算的过程其实就是对目标元素的Key进行hashcode,再对Map的容量进行取模,而JDK 的工程师为了提升取模的效率,使用位运算代替了取模运算,这就要求Map的容量一定得是2的幂。
  2. 作为默认容量,太大和太小都不合适,所以16就作为一个比较合适的经验值被采用了。
  • 为什么默认负载因子为0.75?
  1. 负载因子表示一个数组可以达到的最大的满的程度。这个值不宜太大,也不宜太小。如果太大, 就会有很高的哈希冲突的概率,会大大降低查询速度。如果太小, 那么频繁扩容,就会大大浪费空间。根据数学公式推算。这个值在log(2)的时候比较合理。
  2. HashMap的容量(capacity)有一个固定的要求,那就是一定是2的幂。所以,如果loadFactor是0.75的话,那么和capacity的乘积结果就可以是一个整数。
  • 为什么建议设置HashMap的初始容量? 设置多少合适?
  1. 如果我们没有设置初始容量大小,随着元素的不断增加,HashMap会发生多次扩容,而HashMap中的扩容机制决定了每次扩容都需要重建hash表,是非常影响性能的。
  2. 当HashMap内部维护的哈希表的容量达到75%时(默认情况下),会触发rehash,而rehash的过程是比较耗费时间的。所以初始化容量建议设置成expectedSize/0.75 + 1。
// 正解, guava工具类
Map<String, String> map = Maps.newHashMapWithExpectedSize(7);
// 反例, JDK会默认帮我们计算一个比7大的2的幂, 但是并没有考虑到loadFactor这个因素。
Map<String, String> map = new HashMap(7);
  • 链表与红黑树转换的临界值是多少?
    当链表长度大于8且map容量大于 64 时, 为了查询效率会转换为红黑树结构; 当红黑树长度小于6时,会将红黑树结构转换成链表结构, 可以减少计算量, 提高查询效率.
  • 为什么数组长度要保证为2的幂次方呢?
  1. 只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,即实现了key的定位;
  2. 如果 length 不是 2 的次幂,比如 length 为 15,则 length - 1 为 14,对应的二进制为 1110,在与h&操作,最后一位都为 0 ,所以末尾为1的位置永远都不能存放元素了,数组可以使用的位置比数组长度小了很多,造成空间的浪费, 这意味着进一步增加了碰撞的几率,减慢了查询的效率。

操作相关的问题

  • put方法的原理
    在这里插入图片描述
  • hash方法的原理
    // 通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
  • 数组下标计算原理
// 在满足容量是2的幂次方下, 位运算(&)效率要比取模运算(%)高很多,主要原因是位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。
// 使用位运算代替取模运算,除了性能之外,还有一个好处就是可以很好的解决负数的问题。
(n - 1) & hash
  • HashMap是使用了哪些方法来有效解决哈希冲突的?
  1. 使用链地址法来链接拥有相同hash值的数据;
  2. 使用2次扰动函数来降低哈希冲突的概率,使得数据分布更平均;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值