深入理解JAVA集合系列:HashMap源码解读

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解JAVA集合系列:HashMap源码解读相关的知识,希望对你有一定的参考价值。

初认HashMap

基于哈希表(即散列表)的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键。

HashMap继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。且是不同步的,意味着它不是线程安全的。

 HashMap的数据结构

在java编程语言中,最基本的结构就两种,一个是数组,另一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的。HashMap也不例外,它是一个“链表的数组”的数据结构。从下图中可以看出HashMap的底层就是一个table数组,数组的元素就是Entry。而Entry就是HashMap中的一个存储单元。

技术分享

Entry的数据结构

table数组中的每个元素都是一个由Entry组成的单向链表,理解这句话对理解HashMap非常重要。

技术分享

现在来看下单向链表上一个Entry的数据结构以及源码对其的定义

技术分享

1 static class Entry<K,V> implements Map.Entry<K,V> {
2         final K key;
3         V value;
4         Entry<K,V> next;
5         final int hash;

 HashMap的存取实现

1、存储数据

首先从我编写的这段代码开始,开启HashMap的源码解析之路:

1 public static void main(String[] args)
2     {
3         Map<String,String> hashMap = new HashMap<String,String>();
4         hashMap.put("语文","89");
5         hashMap.put("数学","95");
6         hashMap.put("英语","88");
7     }

在第3行,创建了一个HashMap

1  public HashMap() {
2         this.loadFactor = DEFAULT_LOAD_FACTOR;
3         threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
4         table = new Entry[DEFAULT_INITIAL_CAPACITY];
5         init();
6     }

其中初始容量DEFAULT_INITIAL_CAPACITY为16,loadFactor(负载因子)为0.75。也就是说HashMap在创建的时候构造了一个大小为16的Entry数组。Entry内所有的数据都采用默认值null。

接下来看put方法底层实现是如何的:

 1 public V put(K key, V value) {
 2         if (key == null)
 3             return putForNullKey(value);
 4         int hash = hash(key.hashCode());
 5         int i = indexFor(hash, table.length);
 6         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 7             Object k;
 8             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
 9                 V oldValue = e.value;
10                 e.value = value;
11                 e.recordAccess(this);
12                 return oldValue;
13             }
14         }
15 
16         modCount++;
17         addEntry(hash, key, value, i);
18         return null;
19     }

1、在2、3两行上,可以看出HashMap允许key值为null的存在,并且存放在数据为0的位置上。

2、

以上是关于深入理解JAVA集合系列:HashMap源码解读的主要内容,如果未能解决你的问题,请参考以下文章

深入理解JAVA集合系列二:ConcurrentHashMap源码解读

深入理解JAVA集合系列三:HashMap的死循环解读

深入理解JAVA集合系列三:HashMap的死循环解读

深入理解JAVA集合系列四:ArrayList源码解读

深入理解JAVA集合系列四:ArrayList源码解读

深入Java基础--哈希表HashMap应用及源码详解