前言
HashMap, 是我们在android 程序中最常用的map。HashMap和arrayList 承担了我们在程序中临时存储大量数据的需求。
尤其是hashmap,不但能存储大量的数据,而且其查找某个值的性能另我们记忆深刻.并且hashmap不像数组一样需要大量的连续空间来实现数据的快速写入和读取。可以这样说,hashmap拥有了数组的性能和链表的低内存要求。但是hashmap究竟是怎么实现的呢?我们就来看看其中的原理吧。
源码阅读
基本知识
这里我们在阅读核心源代码之前,先贴一些必要的背景代码。
首先是Hashmap的结构是数组+链表(jdk1.8以后已经修改为数组+红黑树,但是android并没有修改,所以此处不讨论)的结构。借用其他博客的一幅图就是这样的。图片出处。
private static final int MINIMUM_CAPACITY = 4; //数组最小值
private static final int MAXIMUM_CAPACITY = 1 << 30; //数组最大值
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1]; //默认初始数组
static final float DEFAULT_LOAD_FACTOR = .75F; //默认加载因子
transient int size; //hashmap 数据量存储数据的多少
//HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子)
private transient int threshold;
put方法
基础知识介绍完了。首先,我们从put方法开始查看。
@Override public V put(K key, V value) {
if (key == null) { //如果key 为null,则调用专用的null存储函数
return putValueForNullKey(value);
}
int hash = Collections.secondaryHash(key); //计算key的hash值
HashMapEntry<K, V>[] tab = table; //获取当前hashmap的数组
int index = hash & (tab.length - 1); //这里等价于 int index = h