导读:Hashmap是一种常用的、应用广泛的数据类型,最近研究到相关的内容,就正好复习一下。网上关于hashmap的文章很多,但到底是自己学习的总结,就发出来跟大家一起分享,一起讨论。本文是基于JDK1.7分析进行分析。
一.HashMap的数据结构
在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,hashmap也不例外。Hashmap实际上是一个数组和链表的结合体(在数据结构中,一般称之为“链表散列“),请看下图横排表示数组,纵排表示数组元素(实际上是一个链表)。
二.HashMap继承结构图
HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap 最多只允许一条记录的键为 null ,允许多条记录的值为 null 。HashMap 是非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap 方法使 HashMap 具有线程安全的能力,或者使用ConcurrentHashMap。
三.HashMap主要常量、成员变量作用
/**
The default initial capacity - MUST be a power of two.
初始化容量 1左移4位 16
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 <<
4
;
// aka 16
/**
The maximum capacity, used if a higher value is implicitly specified
by either of the constructors with arguments.
存储最大的容量 1左移30位
MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30 ;
/**
The load factor used when none specified in constructor.
HashMap默认,当HashMap中元素数量超过 初始容量*加载因子时候扩容(resize)
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f ;
四.HashMap几种构造方法
/**
2 * 构造方法1:指定初始化容量和加载因子
3 */
4public HashMap(int initialCapacity, float loadFactor) {
5 if (initialCapacity < 0)
6 throw new IllegalArgumentException("Illegal initial capacity: " +
7 initialCapacity);
8 if (initialCapacity > MAXIMUM_CAPACITY)
9 initialCapacity = MAXIMUM_CAPACITY;
10 if (loadFactor <= 0 || Float.isNaN(loadFactor))
11 throw new IllegalArgumentException("Illegal load factor: " +
12 loadFactor);
13
14 this.loadFactor = loadFactor;
15 threshold = initialCapacity;
16 init();
17}
18
19/**
20 * 构造方法2:指定初始化容量,使用默认加载因子0.75
21 */
22public HashMap(int initialCapacity) {
23 this(initialCapacity, DEFAULT_LOAD_FACTOR);
24}
25
26/**
27 * 构造方法3:所有参数使用默认值
28 */
29public HashMap() {
30 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
31}
五.HashMap设置值put及其相关方法
面试中经常会被问到HashMap中如何设置值,若要添加到HashMap中的键值对对应的key已经存在HashMap中,则找到该键值对;然后新的value取代旧的value,并退出!
若要添加到HashMap中的键值对对应的key不在HashMap中,则将其添加到该哈希值对应的链表中,并调用addEntry()
六.HashMap取值get及其相关方法
/**
2 * 通过Key获取对应的值
3 */
4public V get(Object key) {
5if (key == null)
6 return getForNullKey();
7// 获取key的hash值
8int hash = hash(key.hashCode());
9// 在“该hash值对应的链表”上查找“键值等于key”的元素
10for (Entry