HashMap介绍
在一起看HashMap
的源码之前,在这里想要先简要介绍Java8中的HashMap的大体的结构。在前面一章中,我们看到了抽象类AbstractMap
中的许多操作都是基于遍历的方式来进行的,比如查找,这样的操作的效率是很低的。
HashMap中采用了哈希表的方式来提高效率,并用数组来表示这个哈希表,而初始化时为了节约内存,一般不会设置很长的数组,因此不可避免地会出现哈希冲突,即多个对象的哈希值都为同一个数值。这时,HashMap的处理方式是,数组中,每个位置并不是直接放置一个要储存的对象,而是将对象放入链表中,再将这个链表的头节点放在数组中。
因此,我们要通过键查找一个元素的过程就是,先求哈希值,找到哈希值对应的数组中的位置,得到这个位置所对应的链表的头节点,再遍历链表找到我们要找的元素。当然,这里具体来说会有很多细节,比如数组的大小设置及扩容方式,为了解决遍历链表的效率问题,会在链表长度较长时将链表转换成一棵红黑树等等,这些我们可以在看源码的时候再具体了解。
HashMap总体结构
可以看到,HashMap中的内部类与方法还是很多的,这里,我们先来看看其中的内部类Node
,因为这是其它很多操作的基础,了解了它才能比较清楚地去看很多方法的具体实现。
内部类Node<K, V>
首先,我们来看一下内部类Node
的源码:
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}