CodeGym /课程 /JAVA 25 SELF /“自己的字典” — HashMap<K,V&g...

“自己的字典” — HashMap<K,V>

JAVA 25 SELF
第 12 级 , 课程 2
可用

1. 引言

我们已经知道,ArrayList 是一个会自动增长的“可扩展数组”。但它有一个限制:访问元素必须通过编号(索引)。如果我们有一个包含上千人的列表,想找到爱丽丝的电话,要么知道她的索引,要么就得把所有人都遍历一遍。

在实际中,我们经常是按唯一特征来查找数据:

  • 根据姓名找电话号码,
  • 根据护照号码找持有人,
  • 根据登录名找到密码,
  • 根据 id 在数据库中查找对象。

为此我们需要一种结构,能够做到:“拿到键 → 立刻得到值”。在 Java 中,这正是 HashMap<K,V> 的职责。

类比:
想象一本纸质词典。你要找单词“house”的翻译,不必从头翻到尾,而是直接翻到字母“H”,很快就能找到需要的词。HashMap 也是这样:根据键(单词)我们可以瞬时得到值(翻译)。

创建字典

要创建字典,需要指定哪些类型作为,哪些类型作为

import java.util.HashMap;

HashMap<String, String> phonebook = new HashMap<String, String>();

这里:

  • String(第一个类型)是键的类型(人的姓名)。
  • String(第二个类型)是值的类型(电话号码)。

现在 phonebook 就像一本真正的电话簿。

其他变体示例:

HashMap<String, Integer> grades = new HashMap<String, Integer>();  // 姓名 → 分数
HashMap<Integer, String> users = new HashMap<Integer, String>();   // id → 姓名
HashMap<String, Boolean> flags = new HashMap<String, Boolean>();   // 键 → 布尔值

ArrayList 不同,映射没有 add() 方法,但有自己的一套同样有趣的方法。

2. 方法 put(key, value) — 添加一对键值

HashMap 与数组和列表的根本区别在于,它存储的不是单个值,而是键–值对。这让它更像一本真正的词典:每个单词有翻译,每个名字有电话,每个登录名有密码。

示例:

phonebook.put("爱丽丝", "+380501112233");
phonebook.put("鲍勃", "+380671234567");

现在在我们的电话簿中:

  • "爱丽丝" 关联的值是 "+10501112233"
  • "鲍勃" 关联的值是 "+10671234567"

这意味着要获得一个值(电话号码),我们只需知道对应的键(姓名)。

务必记住:键是唯一的。如果我们尝试向已存在的键添加新值,旧值会被覆盖。

phonebook.put("爱丽丝", "+10999999999");

现在爱丽丝只保留了新号码:旧号码丢失了。

结论:put 用于添加或更新条目。键是新的——就创建记录;键已存在——就更新记录。

3. 方法 get(key) — 获取值

要查找某个值,需要知道键。这正是 HashMap 的强项:按键查找非常快,几乎是瞬时的,不管我们有一千条记录还是一百万条。

示例:

System.out.println(phonebook.get("爱丽丝"));

输出:

+10501112233

如果没有这个键,get 会返回 null

System.out.println(phonebook.get("查理")); // null

这表示:“字典中没有键 "查理"”。

4. 方法 containsKey(key) — 检查是否存在

为避免遇到 null,先检查字典中是否有该键会很有用。

示例:

System.out.println(phonebook.containsKey("查理"));

输出:

false

因此我们可以事先判断:

  • 如果没有该键——创建新条目,
  • 如果已有该键——更新它。

常见写法:

if (phonebook.containsKey("爱丽丝")) 
{
    System.out.println("爱丽丝已经有号码了!");
} 
else 
{
    phonebook.put("爱丽丝", "+10111111111");
}

5. 方法 remove(key) — 删除条目

删除同样简单:只需知道键。

phonebook.remove("鲍勃");
System.out.println(phonebook.get("鲍勃"));

输出:

null

现在字典中已没有键为 "鲍勃" 的条目。

6. 遍历所有键值对

很多时候不仅要按特定键取值,还需要把整本“字典”打印出来。为此可以使用 entrySet() 方法。

for (var entry : phonebook.entrySet()) {
    System.out.println(entry.getKey() + " -> " + entry.getValue());
}

示例输出:

爱丽丝 -> +10501112233

这样我们就能同时访问键(entry.getKey())和值(entry.getValue())。

7. 实践:词频统计

来看一个经典问题——统计文本中单词的出现次数。这是 HashMap 用途最典型的示例之一。

String text = "java java core java";
HashMap<String, Integer> freq = new HashMap<String, Integer>();

for (String w : text.split(" ")) 
{
    Integer old = freq.get(w);
    freq.put(w, (old == null) ? 1 : old + 1);
}

System.out.println(freq);

输出:

{core=1, java=3}

我们来详细看看这里发生了什么:

  1. 我们把字符串 "java java core java" 按空格切分成单词。
  2. 对每个单词查看它是否已经在字典中(freq.get(w))。
  3. 如果没有(null),说明是首次出现 → 放入 1
  4. 如果已经存在,说明该单词出现过 → 将值加一。

实际应用:

  • 统计 API 被调用的次数,
  • 统计文本中的词频,
  • 保存仓库中商品的库存数量。

8. 实践:电话簿

我们来写一个稍大一点的应用。

import java.util.HashMap;
import java.util.Scanner;

public class PhonebookApp {
    public static void main(String[] args) 
    {
        HashMap<String, String> phonebook = new HashMap<String, String>();
        Scanner console = new Scanner(System.in);

        while (true) 
        {
            System.out.print("请输入姓名(留空回车退出): ");
            String name = console.nextLine();
            if (name.isEmpty()) break;

            System.out.print("请输入号码: ");
            String phone = console.nextLine();

            phonebook.put(name, phone);
        }

        System.out.println("电话簿:");
        for (var entry : phonebook.entrySet()) 
        {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
    }
}

该程序就像一个小型通讯录。你输入姓名和电话,它们会保存在 HashMap 中。最后可以输出完整列表。字典在真实项目中非常常用。

评论 (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
级别 16,-,Hong Kong
26 七月 2026
示例的电话号码不一样,这翻译质量不太行呀