杰瑞科技汇

Java HashMap核心方法有哪些?

核心概念

在深入方法之前,必须理解 HashMap 的两个核心概念:

Java HashMap核心方法有哪些?-图1
(图片来源网络,侵删)
  1. 键-值对HashMap 存储的是 Entry 对象,每个 Entry 对象包含一个 key 和一个 valuekey 必须是唯一的。
  2. 哈希冲突:不同的 key 可能有相同的哈希值(hashCode() 的结果)。HashMap 通过“链地址法”或“红黑树”来解决冲突,在 Java 8 中,当链表长度超过 8 且数组长度超过 64 时,链表会转换为红黑树以提高查询效率。

构造方法

创建 HashMap 实例时,可以使用不同的构造方法。

方法签名 描述
HashMap() 构造一个具有默认初始容量(16)和默认加载因子(0.75)的空 HashMap
HashMap(int initialCapacity) 构造一个具有指定初始容量和默认加载因子(0.75)的空 HashMap
HashMap(int initialCapacity, float loadFactor) 构造一个具有指定初始容量和加载因子的空 HashMap
HashMap(Map<? extends K, ? extends V> m) 构造一个与指定 Map 具有相同映射关系的新的 HashMap

示例:

// 默认构造
Map<String, Integer> map1 = new HashMap<>();
// 指定初始容量
Map<String, Integer> map2 = new HashMap<>(32);
// 从另一个Map构造
Map<String, Integer> originalMap = new HashMap<>();
originalMap.put("A", 1);
Map<String, Integer> map3 = new HashMap<>(originalMap);

基本操作方法

这些是 HashMap 最常用、最核心的方法。

方法签名 描述 返回值
V put(K key, V value) 将指定的键值对存入此映射。key 已经存在,则更新其对应的 value,并返回旧的 valuekey 不存在,则返回 null V (旧的值)
V get(Object key) 返回指定 key 所映射的 value,如果映射中不包含该 key 的映射关系,则返回 null V (对应的值)
V remove(Object key) 如果存在,从此映射中移除指定 key 的映射关系(及其对应的 value),并返回被移除的 valuekey 不存在,则返回 null V (被移除的值)
boolean containsKey(Object key) 如果此映射包含指定 key 的映射关系,则返回 true boolean
boolean containsValue(Object value) 如果此映射将一个或多个 key 映射到指定 value,则返回 true boolean
boolean isEmpty() 如果此映射不包含键值映射关系,则返回 true boolean
int size() 返回此映射中的键值映射关系数。 int

示例:

Java HashMap核心方法有哪些?-图2
(图片来源网络,侵删)
HashMap<String, Integer> scores = new HashMap<>();
// put
scores.put("Alice", 95);
scores.put("Bob", 88);
scores.put("Alice", 99); // 更新 Alice 的分数
System.out.println("After put: " + scores); // {Bob=88, Alice=99}
// get
Integer aliceScore = scores.get("Alice");
System.out.println("Alice's score: " + aliceScore); // 99
// containsKey
System.out.println("Contains 'Bob'? " + scores.containsKey("Bob")); // true
System.out.println("Contains 'Charlie'? " + scores.containsKey("Charlie")); // false
// remove
Integer removedScore = scores.remove("Bob");
System.out.println("Removed Bob's score: " + removedScore); // 88
System.out.println("After remove: " + scores); // {Alice=99}
// size, isEmpty
System.out.println("Size: " + scores.size()); // 1
System.out.println("Is empty? " + scores.isEmpty()); // false

批量操作方法

这些方法用于一次性操作整个映射。

方法签名 描述 返回值
void putAll(Map<? extends K, ? extends V> m) 从指定映射中将所有映射关系复制到此映射中。 void
void clear() 从此映射中移除所有映射关系,此调用返回后,映射将为空。 void

示例:

HashMap<String, Integer> map1 = new HashMap<>();
map1.put("A", 1);
map1.put("B", 2);
HashMap<String, Integer> map2 = new HashMap<>();
map2.put("C", 3);
map2.put("A", 4); // map1 中也有的 key
// putAll: 将 map2 的内容合并到 map1,key 冲突,map1 的值会被 map2 的值覆盖。
map1.putAll(map2);
System.out.println("After putAll: " + map1); // {A=4, B=2, C=3}
// clear
map1.clear();
System.out.println("After clear: " + map1); // {}
System.out.println("Is empty? " + map1.isEmpty()); // true

视图操作方法

这些方法返回 HashMap 内部数据的“视图”,对视图的修改会直接反映到原始的 HashMap 中,它们是遍历和操作 HashMap 的强大工具。

方法签名 描述 返回值
Set<K> keySet() 返回此映射中包含的 keySet 视图。 Set<K>
Collection<V> values() 返回此映射中包含的 valueCollection 视图。 Collection<V>
Set<Map.Entry<K, V>> entrySet() 返回此映射中包含的 Map.EntrySet 视图,这是最常用的遍历方式。 Set<Map.Entry<K, V>>

示例:

Java HashMap核心方法有哪些?-图3
(图片来源网络,侵删)
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 88);
scores.put("Charlie", 76);
// 1. keySet() - 遍历 key
System.out.println("--- Traversing Keys ---");
for (String name : scores.keySet()) {
    System.out.println("Name: " + name);
}
// 2. values() - 遍历 value
System.out.println("\n--- Traversing Values ---");
for (Integer score : scores.values()) {
    System.out.println("Score: " + score);
}
// 3. entrySet() - 遍历 key-value 对 (推荐方式)
System.out.println("\n--- Traversing Entries ---");
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    System.out.println("Name: " + entry.getKey() + ", Score: " + entry.getValue());
}
// 通过视图修改原 Map
Set<String> keys = scores.keySet();
keys.remove("Bob"); // 直接通过视图的 remove 方法修改原 Map
System.out.println("\nAfter removing 'Bob' via keySet view: " + scores); // {Charlie=76, Alice=95}

其他实用方法

方法签名 描述 返回值
boolean equals(Object o) 比较此映射与指定对象是否相等。 boolean
int hashCode() 返回此映射的哈希码值。 int
Object clone() 返回此 HashMap 实例的浅表副本。 Object

Java 8+ 新增方法

Java 8 为 HashMap 及其父接口 Map 引入了许多非常有用的方法,使其功能更强大。

方法签名 描述 返回值
V getOrDefault(Object key, V defaultValue) 返回指定 key 对应的 valuekey 不存在,则返回 defaultValue V
V putIfAbsent(K key, V value) 只有在 key 不存在时,才将指定的键值对存入此映射。 V (key 不存在,返回 null;如果存在,返回旧值)
boolean remove(Object key, Object value) 只有在 key 存在且其当前映射的 value 与给定的 value 相等时,才移除该条目。 boolean (是否移除成功)
V replace(K key, V value) 只有在 key 存在时,才替换其 value V (key 存在,返回旧值;否则返回 null)
boolean replace(K key, V oldValue, V newValue) 只有在 key 存在且其当前映射的 value 等于 oldValue 时,才将其替换为 newValue boolean (是否替换成功)
void forEach(BiConsumer<? super K, ? super V> action) 对此映射中的每个条目执行给定的操作,直到所有条目都被处理完毕或操作抛出异常。 void
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) 将此映射中的每个条目的值替换为对该条目调用给定函数的结果。 void
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) key 对应的 valuenull 或不存在,则使用给定的函数计算其 value 并存入映射。 V
V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) key 对应的 value 不为 null,则使用给定的函数重新计算其 value V
V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) 使用给定的函数计算指定 key 的新 value V
V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) key 不存在,则将其与给定的 value 关联。key 存在,则用给定的函数对其当前 value 和给定的 value 进行合并,并用结果替换旧 value V

示例 (Java 8+):

HashMap<String, Integer> map = new HashMap<>();
// getOrDefault
System.out.println("getOrDefault 'David': " + map.getOrDefault("David", 0)); // 0
// putIfAbsent
map.putIfAbsent("Alice", 95);
map.putIfAbsent("Alice", 100); // 不会执行,因为 Alice 已存在
System.out.println("After putIfAbsent: " + map); // {Alice=95}
// replace
map.replace("Alice", 98);
System.out.println("After replace: " + map); // {Alice=98}
// replace with old value check
map.replace("Alice", 98, 99); // 会执行,因为旧值是98
map.replace("Alice", 100, 99); // 不会执行,因为旧值不是100
System.out.println("After conditional replace: " + map); // {Alice=99}
// remove with old value check
map.remove("Alice", 99); // 会执行,成功移除
map.remove("Alice", 95); // 不会执行,因为 Alice 已不存在
System.out.println("After conditional remove: " + map); // {}
// computeIfAbsent
map.computeIfAbsent("Bob", k -> 0); // Bob 不存在,则计算并设置其值为 0
map.computeIfAbsent("Bob", k -> 100); // Bob 已存在,此操作不执行
System.out.println("After computeIfAbsent: " + map); // {Bob=0}
// forEach
map.forEach((k, v) -> System.out.println("Key: " + k + ", Value: " + v));
// 输出:
// Key: Bob, Value: 0
// merge
map.merge("Bob", 5, Integer::sum); // Bob 存在,将 0 + 5 = 5 作为新值
map.merge("Charlie", 10, Integer::sum); // Charlie 不存在,直接设置为 10
System.out.println("After merge: " + map); // {Bob=5, Charlie=10}

遍历 HashMap 的几种方式

遍历是 HashMap 的核心操作,主要有以下四种方式:

使用 entrySet() 和 for-each 循环 (推荐)

这是最常用、最高效的方式,因为它通过迭代器直接访问 Map.Entry 对象,避免了多次调用 get() 方法。

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println(key + " : " + value);
}

使用 keySet() 和 for-each 循环

这种方式先遍历 key,然后在循环体中通过 key 获取 value,如果只需要 key,这种方式很方便。

for (String key : map.keySet()) {
    Integer value = map.get(key);
    System.out.println(key + " : " + value);
}

使用 Iterator

entrySet(), keySet(), values() 都返回一个集合,可以使用迭代器进行遍历。

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    // 可以在遍历时安全地删除元素
    if (entry.getValue() < 50) {
        iterator.remove();
    }
}

使用 Java 8 的 forEach 和 Lambda 表达式

代码简洁,函数式风格。

map.forEach((key, value) -> System.out.println(key + " : " + value));
功能类别 核心方法
基本操作 put(), get(), remove(), containsKey(), size()
批量操作 putAll(), clear()
视图操作 keySet(), values(), entrySet()
Java 8+ 增强 getOrDefault(), putIfAbsent(), replace(), remove(), computeIfAbsent(), merge(), forEach()

掌握这些方法,特别是 entrySet() 遍历和 Java 8 引入的新方法,将极大地提高你使用 HashMap 的效率和代码质量。

分享:
扫描分享到社交APP
上一篇
下一篇