HashMap是Java集合框架中Map接口的典型实现类,底层基于哈希表结构,允许存储键值对数据,支持键和值为null,查询和插入效率较高,是日常开发中存储关联数据的常用选择。

HashMap的基本创建
使用HashMap前需要先创建实例,可以通过无参构造指定初始容量和负载因子,也可以直接使用默认参数。默认初始容量为16,负载因子为0.75,当元素数量超过容量乘以负载因子时,HashMap会自动扩容。
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
// 创建默认参数的HashMap实例
Map<String, Integer> defaultMap = new HashMap<>();
// 创建指定初始容量和负载因子的HashMap实例,初始容量20,负载因子0.6
Map<String, Integer> customMap = new HashMap<>(20, 0.6f);
}
}
存储键值对数据
向HashMap中存储键值对需要调用put(K key, V value)方法,该方法会将传入的键值对存入集合中。如果存入的键已经存在,新的值会覆盖原有的值,方法返回的是被覆盖的旧值,如果是新增的键则返回null。
import java.util.HashMap;
import java.util.Map;
public class PutDemo {
public static void main(String[] args) {
Map<String, String> userMap = new HashMap<>();
// 存储第一个键值对,返回null
String result1 = userMap.put("name", "张三");
System.out.println(result1); // 输出null
// 存储重复键的键值对,返回旧值
String result2 = userMap.put("name", "李四");
System.out.println(result2); // 输出张三
System.out.println(userMap.get("name")); // 输出李四
}
}
获取和判断键值对
获取HashMap中对应键的值可以调用get(Object key)方法,如果键不存在则返回null。判断集合中是否包含某个键或某个值,可以分别使用containsKey(Object key)和containsValue(Object value)方法,返回值为布尔类型。
import java.util.HashMap;
import java.util.Map;
public class GetDemo {
public static void main(String[] args) {
Map<Integer, String> scoreMap = new HashMap<>();
scoreMap.put(1, "优秀");
scoreMap.put(2, "良好");
// 获取存在的键对应的值
String score1 = scoreMap.get(1);
System.out.println(score1); // 输出优秀
// 获取不存在的键对应的值
String score3 = scoreMap.get(3);
System.out.println(score3); // 输出null
// 判断键是否存在
boolean hasKey = scoreMap.containsKey(2);
System.out.println(hasKey); // 输出true
// 判断值是否存在
boolean hasValue = scoreMap.containsValue("及格");
System.out.println(hasValue); // 输出false
}
}
遍历HashMap中的键值对
HashMap提供了多种遍历方式,常用的有遍历键集、遍历值集、遍历键值对三种方式。遍历键集可以调用keySet()方法获取所有键的集合,遍历值集可以调用values()方法获取所有值的集合,遍历键值对可以调用entrySet()方法获取所有键值对实体的集合,这种方式效率更高,因为不需要二次查询值。
import java.util.HashMap;
import java.util.Map;
public class IterateDemo {
public static void main(String[] args) {
Map<String, Integer> productMap = new HashMap<>();
productMap.put("苹果", 5);
productMap.put("香蕉", 3);
productMap.put("橙子", 4);
// 方式1:遍历键集,再通过键获取值
System.out.println("遍历键集方式:");
for (String key : productMap.keySet()) {
Integer value = productMap.get(key);
System.out.println(key + ":" + value);
}
// 方式2:遍历值集
System.out.println("遍历值集方式:");
for (Integer value : productMap.values()) {
System.out.println(value);
}
// 方式3:遍历键值对实体,推荐方式
System.out.println("遍历键值对方式:");
for (Map.Entry<String, Integer> entry : productMap.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + ":" + value);
}
}
}
删除键值对
删除HashMap中的键值对可以调用remove(Object key)方法,传入要删除的键,方法会返回被删除的键对应的值,如果键不存在则返回null。也可以调用remove(Object key, Object value)方法,只有当键和值都匹配时才会删除对应的键值对,返回布尔值表示是否删除成功。
import java.util.HashMap;
import java.util.Map;
public class RemoveDemo {
public static void main(String[] args) {
Map<String, String> cityMap = new HashMap<>();
cityMap.put("bj", "北京");
cityMap.put("sh", "上海");
cityMap.put("gz", "广州");
// 删除存在的键
String removedValue = cityMap.remove("sh");
System.out.println(removedValue); // 输出上海
// 删除不存在的键
String notExist = cityMap.remove("sz");
System.out.println(notExist); // 输出null
// 匹配键和值删除
boolean success = cityMap.remove("gz", "广州");
System.out.println(success); // 输出true
}
}
使用注意事项
- HashMap是非线程安全的,如果需要在多线程环境下使用,可以考虑使用
ConcurrentHashMap或者通过Collections.synchronizedMap()方法包装HashMap。 - 作为键的对象需要正确重写
hashCode()和equals()方法,否则可能导致无法正确查找或删除键值对,因为HashMap判断键是否相等依赖这两个方法。 - HashMap的迭代顺序是随机的,不保证元素的存储顺序,如果需要保证顺序可以使用
LinkedHashMap。 - 虽然HashMap允许键和值为null,但如果有多个键为null,只会保留最后一个,因为键不能重复。