返回

深入浅出HashMap,构造函数篇

Android

HashMap 的类结构

public class HashMap<K, V> extends AbstractMap<K, V>
    implements Map<K, V>, Cloneable, Serializable

HashMap继承了AbstractMap并实现了Map接口,AbstractMap是Map接口的抽象实现类,它定义了Map的基本方法,而HashMap则实现了这些方法并提供了具体的实现细节。HashMap的核心数据结构是一个哈希表,它由一个数组和一个链表组成。数组中的每个元素都是一个链表的头结点,链表中的每个元素都是一个键值对。

HashMap 的构造函数

HashMap提供了多种构造函数,以便在不同场景下创建HashMap对象。这些构造函数的签名如下:

public HashMap()
public HashMap(int initialCapacity)
public HashMap(int initialCapacity, float loadFactor)
public HashMap(Map<? extends K, ? extends V> m)

其中:

  • initialCapacity:HashMap的初始容量,即哈希表的大小。
  • loadFactor:HashMap的装载因子,当HashMap的容量达到装载因子时,HashMap将自动扩容。
  • m:要复制到新创建的HashMap中的Map。

哈希算法

HashMap使用哈希算法将键映射到哈希表中的位置。哈希算法是一种将任意大小的数据转换为固定大小的整数的函数。HashMap使用一种称为“除法取模”的哈希算法,将键的哈希值除以哈希表的大小,然后取余数。余数就是键在哈希表中的位置。

碰撞处理

当两个键的哈希值相同,发生这种情况时,称为“碰撞”。碰撞可以导致性能问题,因为多个键将存储在哈希表的同一个位置。为了解决这个问题,HashMap使用链表来处理碰撞。当发生碰撞时,将把键值对添加到哈希表的同一个链表中。

链表

HashMap中的链表是双向链表,每个链表元素都包含一个键值对和指向下一个链表元素的指针。链表的第一个元素是哈希表数组中相应位置的元素。

红黑树

当链表的长度达到8时,HashMap将把链表转换为红黑树。红黑树是一种自平衡二叉搜索树,它可以保证查找、插入和删除操作的时间复杂度为O(log n)。

示例代码

// 创建一个HashMap
HashMap<String, Integer> map = new HashMap<>();

// 向HashMap中添加键值对
map.put("John", 25);
map.put("Mary", 30);
map.put("Bob", 28);

// 从HashMap中获取值
int age = map.get("John");

// 遍历HashMap
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

总结

HashMap是一种高效的键值对存储结构,它具有以下优点:

  • 查找、插入和删除操作的时间复杂度为O(1)。
  • 可以存储任意类型的键和值。
  • 可以自动扩容。
  • 线程不安全。