HashMap 是一个散列表,它存储的内容是键值对(key-value)映射,允许 null 键和 null 值,不保证顺序,不支持线程同步。
HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。
HashMap 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类,且HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。
import java.util.HashMap; // 引入 HashMap 类
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 创建一个 HashMap 对象 Sites, 整型(Integer)的 key 和字符串(String)类型的 value
核心方法详解
1. 添加元素
put(K key,V value) :添加键值对(key-value)
底层机制:
-
计算键的哈希值:(h = key.hashCode()) ^ (h >>> 16)。
-
定位桶位置:index = (n - 1) & hash(n为数组长度)。
-
处理哈希冲突:
链表
长度 < 8:追加到链表末尾。链表长
度 ≥ 8:转换为红黑树(若数组长度 ≥ 64)。
// 引入 HashMap 类
import java.util.HashMap;
public class hashMapPut {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "xinghe");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites);
}
}
2. 访问元素
get(Object key) :获取 key 对应的 value。
时间复杂度:平均O(1),最坏O(n)(哈希冲突严重时)
System.out.println(Sites.get(3));
3. 删除元素
remove(Object key):删除 key 对应的键值对(key-value)。
实现原理:
-
定位桶位置,遍历链表或红黑树找到对应节点。
-
若为树节点,调用TreeNode.removeTreeNode()。
Sites.remove(4);
clear():删除所有键值对。
4. 计算大小
size():计算 HashMap 中的元素数量。
Sites.size()
迭代
可以使用 for-each 来迭代 HashMap 中的元素。
如果只想获取 key,可以使用 keySet() 方法,然后可以通过 get(E key) 获取对应的 value,
如果只想获取 value,可以使用 values() 方法。
import java.util.HashMap;
public class hashMapIteration {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "xinghe");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
// 输出 key 和 value
for (Integer i : Sites.keySet()) {
System.out.println("key: " + i + " value: " + Sites.get(i));
}
// 返回所有 value 值
for(String value: Sites.values()) {
// 输出每一个value
System.out.print(value + ", ");
}
}
}
应用场景:词频统计
String text = "apple banana apple orange";
Map<String, Integer> frequency = new HashMap<>();
for (String word : text.split(" ")) {
frequency.put(word, frequency.getOrDefault(word, 0) + 1);
}
// 输出:{apple=2, banana=1, orange=1}