HashMap底层原理详解
本文旨在系统学习常用容器 HashMap 的使用及底层实现原理,欢迎指正。
前言
HashMap 是JAVA中常用的一种容器类(数据结构),也是JAVA开发面试中常问的考点,应深入理解其工作原理。
一、HashMap 底层数据结构
最主要的三个类(接口)就是 HashMap,AbstractMap和 Map 了,下面来介绍一下 AbstractMap、Map及重要的内部类和接口。
1. AbstractMap 类
这个抽象类是 Map 接口的骨干实现,以求最大化的减少实现类的工作量。为了实现不可修改的 map,程序员仅需要继承这个类并且提供 entrySet 方法的实现即可。它将会返回一组 map 映射的某一段。通常,返回的集合将在AbstractSet 之上实现。这个set不应该支持 add 或者 remove 方法,并且它的迭代器也不支持 remove 方法。
2. Map 接口
Map 接口定义了 key-value 键值对的标准。一个对象支持 key-value 存储。Map不能包含重复的 key,每个键最多映射一个值。这个接口代替了Dictionary 类,Dictionary是一个抽象类而不是接口。
Map 接口提供了三个集合的构造器,它允许将 map 的内容视为一组键,值集合或一组键值映射。map的顺序定义为map映射集合上的迭代器返回其元素的顺序。一些map实现,像是TreeMap类,保证了map的有序性;其他的实现,像是HashMap,则没有保证。
为了实现可修改的 map,程序员必须额外重写这个类的 put 方法(否则就会抛出UnsupportedOperationException),并且 entrySet.iterator() 返回的 iterator 必须实现 remove() 方法。
3. 重要内部类和接口
a. Node 接口:Node节点是用来存储HashMap的一个个实例,它实现了 Map.Entry接口,我们先来看一下 Map中的内部接口 Entry 接口的定义:
// 一个map 的 entry 链,这个Map.entrySet()方法返回一个集合的视图,包含类中的元素,
// 这个唯一的方式是从集合的视图进行迭代,获取一个map的entry链。这些Map.Entry链只在迭代期间有效。
interface Entry<K,V> {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
}
b. Node 节点:Node节点是用来存储HashMap的一个个实例,节点中会存储四个属性,hash值,key,value,指向下一个Node节点的引用:
// hash值
final int hash;
// 键
final K key;