HashMap面试题

1 、为什么hashmap 扩容是2的倍数?

hashmap put 的时候直接去key的hash值方法

public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}

key的hashcode 异或 key的hashcode的位移
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

jdk 1.7 取数组角标位置
static int indexFor(int h, int length) {
return h & (length-1);

上述代码也相当于对length求模。 注意最后return的是h&(length-1)。如果length不为2的幂,比如15。那么length-1的2进制就会变成1110。在h为随机数的情况下,和1110做&操作。尾数永远为0。那么0001、1001、1101等尾数为1的位置就永远不可能被entry占用。这样会增加了碰撞的几率,减慢了查询的效率,造成空间的浪费。 length-1 二进制中为1的位数越多,那么分布就平均。

2的倍数是为了 & 的时候叫数据在数组上均匀分布

2 、hashmap的几种构造 ?构造数组的长度和长度+因子的区别?

在这里插入图片描述
hashmap 容量初始化 还是默认了初始因子
在这里插入图片描述
在这里插入图片描述

3、 hashmap 数组的最大长度,hashmap是不是无限大?

最大长度为1<<30
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、hashmap 构造初始化容量13因子0.8,那数组的长度就是 13 吗?

答案不是
源码中的数组初始化长度做了校正,还是2的倍数 最小默认为16
在这里插入图片描述

5 、hashmap 为解决hash 冲突使用链表 为啥都是每次放到链表的表头?

java 最近使用原则 索引新的数据放在了表头

6 、链表的上的hash都是一样吗? hash 不同的两个值会在一个链表上吗?

会不会在一个链表上 是通过 hash值和数组的长度-1 & 运算,或造成 key的hash不同,但是落在数组角标相同的位置
最容易出现的情况就是 hash构造的时候参数(12,1.5) 因为容量因子的扩大,会造成更多的不同的hash 落在同一个角标位置。所以就有了链表上多个entry 进行判断的时候
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;

7、链表的作用?

hash不同key 也可能在一个链表上,根据判断后相同key直接覆盖,不同的key只能新建一个node
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;

这样子快

Map<String, Object> map = new HashMap<>();
map.put("1", 1);
map.put("2", 2);
for (Map.Entry<String, Object> entry : map.entrySet()) {
    System.out.println(entry);
    System.out.println(entry.getKey());
    System.out.println(entry.getValue());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值