HashMap 是 Java 中常用的数据结构之一,hash 是散列的意思,Map 有映射表的意思,于是 HashMap 就是散列表的意思,它存储的内容是键值对。Java8 之前,HashMap 在存储大量数据时,查询效率并不是非常高,但在 Java8,HashMap 的底层实现发生了一些改变,引进了一些新的技术,如当索引值大于或等于 8 时,数据结构将会由链表转换为红黑树,目的是为了提高数据的查询效率等。
一、HashMap 的继承结构
HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null(此时哈希值为 0),不支持线程同步,HashMap 同时还继承了 AbstractMap 类,实现了 Cloneable 接口和 Serializable 接口。
HashMap继承结构图
上图中,黄色表示类(Class),绿色表示接口(Interface),实线表示继承(extends),虚线表示实现(implements)。
HashMap 一般被当作字典来使用(Map 就是字典),因此 HashMap 是无序的,即不会记录插入的顺序。但这并不代表着 Java 里面没有字典类,只不过字典类 Dictionary 已经不常用了而已。字典这种数据结构由很多的实现,在其他语言中都有类似的存在,如 C++ std 中的 Map,以及 Python 中的内置类 dict。
二、数据结构 —— 字典
我们都知道一些常用的数据结构,如数组、链表等,它们都是一维的线性数据结构,它们的展现形式大致是这样的:
数组和链表
字典实际就相当于一维线性数据结构的扩展,从一维扩展到了二维,但并不是完全的二维,它一般在二维层面上只有一对数据(两个互相关联的数据),一般可以表示为下图:
字典
再扩展一点,每对数据中不一定是存储简单的数字,也可以是一种数据结构。字典中的每对数据都是一个键值对,一个是键,一个是值,值用于存储数据,键用于查询,因此不能有重复的键,值就没有任何限制了。
三、HashMap 的基本方法
类 HashMap 位于 java.util 包中,它的常见方法如下:
方法 | 描述 |
clear | 删除 HashMap 中的所有键值对 |
clone | 复制一份 HashMap |
isEmpty | 判断 HashMap 是否为空 |
size | 计算 HashMap 中键/值对的数量 |
put | 将键/值对添加到 HashMap 中 |
putAll | 将所有键/值对添加到 HashMap 中 |
putIfAbsent | 如果 HashMap 中不存在指定的键,则将指定的键/值对插入到 HashMap 中 |
remove | 删除 HashMap 中指定键 key 的映射关系 |
contasinsKey | 检查 HashMap 中是否存在指定的 key 对应的映射关系 |
containsValue | 检查 HashMap 中是否存在指定的 value 对应的映射关系 |
replace | 替换 HashMap 中是指定的 key 对应的 value |
replaceAll | 将 HashMap 中的所有映射关系替换成给定的函数所执行的结果 |
get | 获取指定 key 对应对 value |
getOrDefault | 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值 |
forEach | 对 HashMap 中的每个映射执行指定的操作 |
entrySet | 返回 HashMap 中所有映射项的集合集合视图 |
keySet | 返回 HashMap 中所有 key 组成的集合视图 |
values | 返回 HashMap 中存在的所有 value 值 |
merge | 添加键值对到 HashMap 中 |
compute | 对 HashMap 中指定 key 的值进行重新计算 |
computeIfAbsent | 对 HashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 HashMap 中 |
computeIfPresent | 对 HashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 HashMap 中 |
举几个例子:
importjava.util.HashMap; publicclassTest { publicstaticvoidmain(String[] args) { HashMap<Integer, String>hashMap=newHashMap<>(); hashMap.put(1, "Java"); // 添加键值对hashMap.put(2, "Java8"); // 添加键值对System.out.println(hashMap); // Output: {1=Java, 2=Java8}System.out.println(hashMap.get(1)); // Output: JavahashMap.remove(1); // 移除键为 1 的键值对System.out.println(hashMap.size()); // Output: 1 } }