JAVA-HashMap源码-常量及构造器

HashMap(jdk1.8)

HashMap的类定义:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

HashMap继承了AbstractMap抽象类,实现了Map接口、可克隆接口、可序列化接口
AbstractMap抽象类:实现了Map接口,提供了get、set、size、isEmpty、containsKey、containsValue等等公共方法

HashMap的一些静态常量:
1、DEFAULT_INITIAL_CAPACITY:默认初始容量大小16
2、MAXIMUM_CAPACITY:最大容量大小为1024*1024*1024
3、DEFAULT_LOAD_FACTOR:默认加载因子为0.75f
4、TREEIFY_THRESHOLD:链表转换为红黑树的阈值为8
5、UNTREEIFY_THRESHOLD:红黑树转为链表的阈值为6
6、MIN_TREEIFY_CAPACITY:链表转换为红黑树要求表容量大小不低于64,否则进行扩容

HashMap提供了四个构造器方法:
1、public HashMap(int initialCapacity, float loadFactor),指定容量和加载因子
代码如下:
public HashMap(int initialCapacity, float loadFactor) {
//初始化容量不能小于0
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
//初始化容量大于最大阈值,则按最大阈值算
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
//加载因子不能小于等于0,不能是非数字
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
//调用tableSizeFor方法目的是为了得到最接近initialCapacity且是2的倍数的真实容量值
this.threshold = tableSizeFor(initialCapacity);
}
tableSizeFor方法很巧妙地运用了位移及或运算,这里我们提出来看一下
代码如下:
static final int tableSizeFor(int cap) {
//这里减一,后面会再加一,后面的加一操作是关键,可以得到2的整数倍的值
int n = cap - 1;
//向右逻辑位移1位然后与原值进行或运算,头两位变为11
n |= n >>> 1;
//向右逻辑位移2位然后与原值进行或运算,头四位变为1111
n |= n >>> 2;
//向右逻辑位移4位然后与原值进行或运算,头八位变为11111111
n |= n >>> 4;
n |= n >>> 8;
//一直类推,将低位都变为1,即 ...001111111...1
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

2、public HashMap(int initialCapacity),指定初始容量
代码如下:
public HashMap(int initialCapacity) {
//使用默认加载因子:0.75f
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
3、public HashMap(),无参
代码如下:
public HashMap() {
//指定加载因子为默认值
this.loadFactor = DEFAULT_LOAD_FACTOR;
}
4、public HashMap(Map<? extends K, ? extends V> m),
代码如下:
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
//将传入的表的元素放入新表中
putMapEntries(m, false);
}

注:
1、上面的构造器中只是初始化了容量和加载因子并没有实际创建表,实际创建表是在执行putVal操作时,进一步调用resize,然后创建表


猜你喜欢

转载自blog.csdn.net/ignorewho/article/details/80475092
今日推荐