- DEFAULT_INITIAL_CAPACITY 1 << 4; 初始化容量为16,必须是2的幂
- MAXIMUM_CAPACITY 1 << 30; 最大容量为2的30次方
- DEFAULT_LOAD_FACTOR = 0.75; 默认加载因子0.75,因此初始情况下,当键值对的数量大于 16 * 0.75 = 12 时,就会触发扩容
- TREEIFY_THRESHOLD = 8; 由链表转换成树的阈值,当某个箱子中,链表长度大于 8 时,有可能会转化成树
- UNTREEIFY_THRESHOLD = 6; 由树转换成链表的阈值,在哈希表扩容时,如果发现链表长度小于 6,则会由树重新退化为链表
- MIN_TREEIFY_CAPACITY = 64; 在转变成树之前,还会有一次判断,只有键值对数量大于 64 才会发生转换
- Node静态内部类:
Node<K,V>实现了Map的内部接口Map.Entry<K,V>,它表示Map中的一个实体(一个key-value对)提供了getKey();getValue();hashCode();setValue(V newValue);equals(Object o);等方法
注意,在Node中成员变量hash是指key对应的hash值
其成员方法hashCode为node对象的hash值
在成员变量table中引用的就是这个Node - static final int hash(Object key):
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // key为空,返回0,否则返回原hash值和原hash值无符号右移16位的值按位异或的结果
}
由于覆盖equals()需要覆盖hashCode(),所以hashCode()有时并不十分完美,比如只和高位有关等等,因此需要再hash()一下
方法在JDK1.8中保证了对象的hashCode的高16位的变化能反应到低16位中,相比较而言减少了过多的位运算 - static Class<?> comparableClassFor(Object x):
当传入对象的运行时类型符合”class C implements Comparable”这个条件时,返回对象的运行时类型,否则返回nullstatic Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) { // 判断是否实现了Comparable
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class) // bypass checks
return c; // 如果是String类型,则直接返回
if ((ts = c.getGenericInterfaces()) != null) { // 判断是否有直接实现的接口
for (int i = 0; i < ts.length; ++i) {
if (((t = ts[i]) instanceof ParameterizedType) && // 判断该接口是否实现了泛型
((p = (ParameterizedType)t).getRawType() == // 获取接口不带参数部分的类型对象
Comparable.class) && // 该类是Comparable类型
(as = p.getActualTypeArguments()) != null && // 获取泛型参数类型数组
as.length == 1 && as[0] == c) // type arg is c // 只有1个泛型参数,并且该实现是该类本身
return c; // 返回该类
}
}
}
return null;
} - ParameterizedType:
getActualTypeArguments()
返回 这个 Type 类型的参数的实际类型数组。 如 Map<String,Person> map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array (获取该类实现的泛型类"<>"内的类型)
getClass().getGenericInterfaces()
返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现 (获取该类实现的接口的全路径名)
getRawType()
返回的是当前这个 ParameterizedType 的类型。如 Map<String,Person> map这个ParameterizedType返回的是Map类的全限定类名的Type Array() (获取该类实现的泛型类的全限定名) - static int compareComparables(Class<?> kc, Object k, Object x):
判断x是否为空,并且x是否为kc类型,如果为真,则使用((Comparable)k).compareTo(x)),进行大小比较,否则返回0 - static final int tableSizeFor(int cap):
(不考虑大于最大容量的情况)是返回大于输入参数且最近的2的整数次幂的数。比如10,则返回16
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位操作部分:先来假设n的二进制为01xxx...xxx
对n右移1位:001xx...xxx,再位或:011xx...xxx
对n右移2为:00011...xxx,再位或:01111...xxx
此时前面已经有四个1了,再右移4位且位或可得8个1
同理,有8个1,右移8位肯定会让后八位也为1
综上可得,该算法让最高位的1后面的位全变为1
最后再让结果n+1,即得到了2的整数次幂的值了