[关闭]
@Cesar 2016-02-20T05:49:32.000000Z 字数 1027 阅读 1225

Java中的HashMap源码分析

Java 算法

概论

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
HashMap的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。

源码

生成hash值方法

在hashMap中,对于每一个Key,都要生成一个该Key的hash值,源码如下:

  1. final int hash(Object k) {
  2. int h = 0;
  3. if (useAltHashing) {
  4. if (k instanceof String) {
  5. return sun.misc.Hashing.stringHash32((String) k);
  6. }
  7. h = hashSeed;
  8. }
  9. h ^= k.hashCode();
  10. h ^= (h >>> 20) ^ (h >>> 12);
  11. return h ^ (h >>> 7) ^ (h >>> 4);
  12. }

将Key映射到Table中

该方法将上一步产生的hash值进行与表格进行映射,是一个环形的映射方法

  1. static int indexFor(int h, int length) {
  2. return h & (length-1);
  3. }

容量限制

在hashMap中有两个重要的参数,“容量”和“加载因子”,默认初始容量为16,加载因子为0.75.容量最大为2^30。 容量*加载因子即为阈值,当存在hashMap中的键值对的数量大于阈值的时候,需要将Table的size*2.然后将之前的Key重新映射到新的Table中。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注