HashMap源码--(一)属性

HashMap源码–(一)属性

HashMap是容器Map的实现类。

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

HashMap继承了AbstractMap,AbstractMap是个抽象类,实现了Map,并实现了Map的主干方法,这样要实现Map只要继承AbstractMap并实现对应的entrySet()方法就可以。
这里HashMap继承了AbstractMap有实现了Map主要是让程序员明显的看到HashMap是Map的子类。
HashMap实现了Cloneable,表名调用Object.clone() 方法可以合法地对该类实例进行按字段复制,否则调用会报错。
HashMap实现Serializable,表名可以序列化。
HashMap的一些属性需要简述一下,以便理解其原理和方法:

/**
 * 默认的初始容量,必须是2的幂.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
 * 最大的容量值,用于通过构造器指定更大的值时所给定的值
 * 也就是容量值必须小于等于1 << 30(2的30次幂)
 */
static final int MAXIMUM_CAPACITY = 1 << 30;

/**
 * 默认的加载因子.
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
 * table是HashMap中存值的数组,它的长度是按需变化的,它的长度                 *(length)通常是2的幂指数个.
 */
transient Entry[] table;

/**
 *Map中存放键值对的个数
 */
transient int size;

/**
 * 加载阈值,下一次调整Map长度的临界值 (capacity * load factor).
 * @serial
 */
int threshold;

/**
 * HashMap的加载因子,在构造器中指定的.
 * @serial
 */
final float loadFactor;

/**
 * HashMap对象被结构性修改的次数, 譬如:put、remove, 
 * rehash操作 。这个属性主要用于多线程并发时发生的fail-fast。
 */
transient int modCount;

/**
 * 应用在字符串键的备选哈希函数的容量阈值,这个备选哈希函数可
 *以减少由于弱哈希值引起碰撞的概率。
 *默认值是Integer.MAX_VALUE
 *它可能被系统配置的属性值{@code jdk.map.althashing.threshold}
 *覆盖。如果改属性值是1,备选哈希函数将被使用,如果是-1,备选
 *哈希函数将永远不会被使用。
 */
static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;

HashMap实际也是用数组来存储元素,数组的大小可以在创建时指定大小,如果不指定则用默认的构造器容量为16,数组的大小是2的幂指数。HashMap中Entry[] table是用来接收元素,它的大小就是构造器指定的大小或默认的大小,即length。
size与length都是大小,但有不同的作用。length是HashMap的容量,即最多存储元素的数量。size是HashMap当前的存储的数量。
例:
Map map = new HashMap();
map.put(1, "one");
map.put(2, "two");

这里创建HashMap时用的是默认构造器,length为16,添加了两个元素,size是2。
HashMap在size/length达到一定比例时,需要扩大容量。加载因子loadFactor就是这个比例。加载因子可以在创造时指定,也可以用默认的值。对应的扩容的临界值size就是阈值threshold。当添加元素的数量达到阈值,容量会扩大2倍。
例如:容量length为16、加载因子loadFactor为0.75的HashMap,阈值threshold则为16*0.75=12,也就是在size达到阈值即12时,HashMap的容量变为16*2=32。

你可能感兴趣的:(java)