这次主要针对容量初始化问题进行回顾。一步一步看
1.首先看一下构造方法
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);//第一个为用户输入的初始容量,第二个为默认的扩容因子,0.75f
}
2.一步一步往上看,作用很简单,保证用户输入的初始值在最大容量范围内
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);
}
3.第三部,也就是返回阈值的方法
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;
}
这里注意>>> 和|=这两个符号,|=的作用是按位取或,
比较一下>>和>>>的区别。>>>是右移N位,无符号右移,
>>>与>>唯一的不同是它无论原来的最左边是什么数,统统都用0填充。
——比如你的例子,byte是8位的,-1表示为byte型是11111111(补码表示法)
b>>>4就是无符号右移4位,即00001111,这样结果就是15。
右移运算符>>使指定值的所有位都右移规定的次数。右边移出去的部分扔掉不要,左边空出来的部分用原来的数字填充(这就是所谓的带符号右移)
——比如说5,右移后为00000010。
——你给的例子,假设x=-12,表示为32位int型就是
11111111111111111111111111110100
x>>3即带符号右移3位,结果是
11111111111111111111111111111101,化为十进制等于-3
这段代码的最终作用就是将category变为原来的二倍,,如果是负数,则变为1.