赞
踩
转载本文章请标明作者和出处
本文出自《爱喝纯净水的南荣牧歌》
最近我们发现HashMap是大厂面试官的最爱之一,面试的提问频率可以说超过60%,那怎么办,盘他!!!
首先我们去new一个HashMap的时候,可以在构造函数中指定它的初始容量(阿里的代码检查器也要求我们最好指明);
我们打开HashMap的这个构造函数看一下;
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
前面都是给负载因子赋值的操作,最后我发现调用了一个tableSizeFor(int)方法;追上去,看一下;
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
通过注释我们可以发现,这是要给出一个2的整数幂的一个操作,其实也就是给出第一个比cap大的2的整数幂;
那么这几行代码是则呢么办到的呢?
先不管开始的减一和最后的加一操作,那几个位运算和或等于又代表着什么呢?
假设,我们给定的cap值为9;那么n=9-1等于8;
如下为8的二进制表达;
那么我们把8无符号右移一位,得到;
这两个数,我们做一下|=操作(当前位上有1就是1,全为0才是0),得到;
再把这个数,无符号右移两位得到;
上面两个数再做|=,得到;
最后的
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
得出的还是这个结果,然后再加1等于16,恰好是离9最近的2的整数幂;
那为什么要一直无符号右移16位呢?
因为int类型刚好为32位,最后的右移16位,刚好能覆盖整个int类型;
那么为什么要先减去1最后再加上1呢?
因为如果cap等于8的话,直接操作的话结果会是16不会是8,就是如果传入一个正好为2的整数幂的数,不会返回这个数本身;
如果面试官在问你HashMap的时候你可以对比说一下jdk7和jdk8的区别的话,相信面试官一定会眼前一亮;
jdk8相较于jdk7做了比较大的升级;具体可以分为一下几点;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。