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,且性能差、已过时,新代码不要使用。

对比项HashMapHashtable
线程安全是(方法加锁)
null 键 / 值允许不允许
现状新代码首选旧代码遗留

小结:HashMap 存键值对,读写平均 O(1);自定义键要同时重写 equals 和 hashCode;允许一个 null 键;非线程安全,并发场景用 ConcurrentHashMap。

笔记加载中…