Java HashMap
HashMap 以键值对(key-value)存储数据,能用键快速完成存、取、删,平均复杂度 O(1),是 Java 中最常用的 Map 实现,适合一切“按编号 / 名字查信息”的场景。
键值对与基本用法
键值对存储:键唯一,重复 put 同一键会覆盖旧值;值可重复。
import java.util.HashMap;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("小明", 90); // 放入键值对
map.put("小红", 85);
map.put("小明", 95); // 键已存在:覆盖旧值
System.out.println(map); // 输出:{小红=85, 小明=95}
System.out.println(map.get("小明")); // 输出:95
System.out.println(map.containsKey("小红")); // 输出:true
map.remove("小红");
System.out.println(map.size()); // 输出:1
}
}
常用方法速记:put(key, value) 添加(覆盖时返回旧值);get(key) 取键对应的值,键不存在返回 null;containsKey / containsValue 判断是否包含;remove(key) 删除并返回被删值;keySet() / values() / entrySet() 分别得到键集合、值集合、键值对条目集合;size() / isEmpty() / clear() 管大小与清空。
遍历方式
import java.util.HashMap;
import java.util.Map;
public class LoopMap {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
// 只遍历键:for (String k : map.keySet());只遍历值:for (Integer v : map.values())
for (Map.Entry<String, Integer> e : map.entrySet()) {
System.out.println(e.getKey() + "=" + e.getValue());
}
}
}
// 输出示例(HashMap 无序,顺序可能不同):a=1、b=2
键唯一性:为什么重写 equals 与 hashCode
HashMap 把键的 hashCode 当作“桶号”定位存放位置,再用 equals 判断键是否相同;默认两者按对象地址比较,内容相同的对象会被当成不同键。若只重写 equals 而 hashCode 不同,相等的键仍会落进不同桶,get 依旧找不到——所以必须同时重写,并保证 equals 相等则 hashCode 相等。
import java.util.HashMap;
import java.util.Objects;
class Student {
String name;
Student(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Student)) return false;
return Objects.equals(name, ((Student) o).name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public class KeyDemo {
public static void main(String[] args) {
HashMap<Student, String> map = new HashMap<>();
map.put(new Student("张三"), "一班");
// 内容相同的新对象能查到:equals/hashCode 生效
System.out.println(map.get(new Student("张三"))); // 输出:一班
}
}
null 键与 Hashtable 区别
HashMap 允许一个 null 键和任意多个 null 值,但非线程安全,多线程并发增删需改用 ConcurrentHashMap。旧类 Hashtable 虽线程安全(方法加锁)但不允许 null,且性能差、已过时,新代码不要使用。
| 对比项 | HashMap | Hashtable |
|---|---|---|
| 线程安全 | 否 | 是(方法加锁) |
| null 键 / 值 | 允许 | 不允许 |
| 现状 | 新代码首选 | 旧代码遗留 |
小结:HashMap 存键值对,读写平均 O(1);自定义键要同时重写 equals 和 hashCode;允许一个 null 键;非线程安全,并发场景用 ConcurrentHashMap。