Java 实例 – HashMap遍历(建议收藏)

Java 实例 – HashMap遍历:从入门到精通

在 Java 开发中,HashMap 是最常用的集合类型之一,它以键值对的形式存储数据,具备高效的查找和插入性能。然而,很多初学者在面对 HashMap 数据遍历时,常常感到困惑:到底该用哪种方式?for 循环?增强 for 循环?还是迭代器?别急,今天我们就来系统梳理 Java 实例 – HashMap遍历 的各种方式,结合实际场景,帮你彻底掌握。


为什么需要遍历 HashMap?

想象一下,你正在开发一个学生管理系统,每个学生都有一个唯一的学号(键)和对应的姓名(值)。当你要显示所有学生信息时,就必须把 HashMap 中的每一个键值对“拿出来”查看,这个过程就是“遍历”。

HashMap 本身不直接支持索引访问,所以必须借助特定方式来逐个读取键和值。掌握遍历方法,是使用 HashMap 的基础技能。


方法一:使用 for-each 循环遍历键值对(推荐)

这是最简洁、最常用的方式,尤其适合初学者。我们先看代码:

import java.util.HashMap;
import java.util.Map;

public class HashMapTraversalExample {
    public static void main(String[] args) {
        // 创建 HashMap 并添加数据
        Map<String, String> studentMap = new HashMap<>();
        studentMap.put("001", "张三");
        studentMap.put("002", "李四");
        studentMap.put("003", "王五");

        // 使用 for-each 遍历键值对
        for (Map.Entry<String, String> entry : studentMap.entrySet()) {
            String id = entry.getKey();      // 获取键(学号)
            String name = entry.getValue();  // 获取值(姓名)
            System.out.println("学号: " + id + ", 姓名: " + name);
        }
    }
}

代码解析:

  • studentMap.entrySet():返回一个包含所有键值对的 Set 集合,每个元素是 Map.Entry 类型。
  • for (Map.Entry<String, String> entry : ...):增强 for 循环,自动遍历 Set 中的每一个 entry。
  • entry.getKey():获取当前键(如学号)。
  • entry.getValue():获取当前值(如姓名)。

这种方式逻辑清晰,代码简洁,是绝大多数场景下的首选。


方法二:通过键集遍历(先获取键,再查值)

如果你只需要遍历键,或者想在遍历时对键进行额外处理,可以先获取所有键,再通过键查找值。

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class TraverseByKey {
    public static void main(String[] args) {
        Map<String, Integer> scoreMap = new HashMap<>();
        scoreMap.put("数学", 95);
        scoreMap.put("英语", 87);
        scoreMap.put("物理", 92);

        // 获取所有键的集合
        Set<String> keys = scoreMap.keySet();

        // 遍历键,并根据键获取对应的值
        for (String subject : keys) {
            Integer score = scoreMap.get(subject);  // 通过键获取值
            System.out.println("科目: " + subject + ", 分数: " + score);
        }
    }
}

说明:

  • scoreMap.keySet():返回所有键的 Set 集合。
  • scoreMap.get(subject):根据键获取对应的值。
  • 优点:适合需要操作键的场景,比如筛选特定键。
  • 缺点:每次获取值都要调用 get(),性能略低于直接遍历 entry。

方法三:使用 Iterator 迭代器遍历

迭代器是 Java 集合框架中非常强大的工具,尤其适合在遍历过程中需要删除元素的场景。

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class TraverseWithIterator {
    public static void main(String[] args) {
        Map<String, String> userMap = new HashMap<>();
        userMap.put("admin", "管理员");
        userMap.put("user1", "普通用户");
        userMap.put("guest", "访客");

        // 获取迭代器
        Iterator<Map.Entry<String, String>> iterator = userMap.entrySet().iterator();

        // 使用 while 循环遍历
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();  // 获取下一个元素
            String role = entry.getKey();
            String description = entry.getValue();
            System.out.println("角色: " + role + ", 描述: " + description);

            // 示例:删除某个元素(注意:必须通过迭代器删除,否则会抛出异常)
            if ("guest".equals(role)) {
                iterator.remove();  // 安全删除当前元素
                System.out.println("已删除访客角色");
            }
        }

        // 输出剩余元素
        System.out.println("删除后剩余元素: " + userMap);
    }
}

重点提醒:

  • iterator.hasNext():判断是否还有下一个元素。
  • iterator.next():获取下一个元素,且指针后移。
  • iterator.remove()唯一合法的删除方式,在遍历中删除元素时必须使用此方法。
  • 如果直接调用 map.remove(),会触发 ConcurrentModificationException 异常。

方法四:使用 Java 8 Stream API(现代写法)

Java 8 引入了 Stream,让集合操作更加函数式。对于 HashMap 遍历,Stream 也是不错的选择。

import java.util.HashMap;
import java.util.Map;

public class TraverseWithStream {
    public static void main(String[] args) {
        Map<String, Double> priceMap = new HashMap<>();
        priceMap.put("苹果", 5.5);
        priceMap.put("香蕉", 3.8);
        priceMap.put("橙子", 6.2);

        // 使用 Stream 遍历
        priceMap.forEach((fruit, price) -> {
            System.out.println("水果: " + fruit + ", 价格: " + price + " 元");
        });

        // 也可以结合 filter 进行筛选
        System.out.println("\n价格高于 5 元的水果:");
        priceMap.entrySet().stream()
                .filter(entry -> entry.getValue() > 5.0)
                .forEach(entry -> System.out.println(entry.getKey() + " -> " + entry.getValue()));
    }
}

优势:

  • 代码更简洁,语义清晰。
  • 支持链式调用(如 filter、map、sorted 等)。
  • 适合复杂的数据处理逻辑。

注意:

  • forEach 是 Java 8 引入的方法,适用于 JDK 8 及以上版本。
  • entrySet().stream() 是标准写法,避免直接对 map 操作。

方法五:传统 for 循环遍历(不推荐,但需了解)

虽然不推荐,但有些老项目仍会用这种方式,了解它有助于阅读旧代码。

import java.util.HashMap;
import java.util.Map;

public class TraverseWithTraditionalFor {
    public static void main(String[] args) {
        Map<String, String> cityMap = new HashMap<>();
        cityMap.put("北京", "首都");
        cityMap.put("上海", "经济中心");
        cityMap.put("广州", "南方门户");

        // 获取所有键值对的数组(不推荐,性能差)
        Object[] entries = cityMap.entrySet().toArray();

        // 传统 for 循环遍历
        for (int i = 0; i < entries.length; i++) {
            Map.Entry entry = (Map.Entry) entries[i];
            System.out.println("城市: " + entry.getKey() + ", 类型: " + entry.getValue());
        }
    }
}

为什么不推荐?

  • toArray() 会创建新数组,增加内存开销。
  • 类型转换(Map.Entry)容易出错。
  • 性能不如其他方式。

五种方法对比总结

方法 优点 缺点 适用场景
for-each + entrySet 简洁、高效、可读性强 稍微复杂 90% 的遍历场景
keySet + get 适合操作键 每次 get 有性能损耗 需要处理键的逻辑
Iterator 支持安全删除 代码稍长 遍历时需删除元素
Stream API 函数式、支持链式操作 学习成本略高 复杂数据处理
传统 for + toArray 通用性强 性能差、冗余 避免使用

实际案例:用户登录日志分析

假设我们有一个日志系统,记录用户登录时间:

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

public class LoginLogAnalysis {
    public static void main(String[] args) {
        Map<String, LocalDateTime> loginLogs = new HashMap<>();
        loginLogs.put("user1", LocalDateTime.of(2025, 4, 5, 10, 30));
        loginLogs.put("user2", LocalDateTime.of(2025, 4, 5, 11, 15));
        loginLogs.put("user3", LocalDateTime.of(2025, 4, 5, 9, 45));

        // 使用 Stream API 遍历并筛选最近登录的用户
        System.out.println("最近登录的用户(10:00 后):");
        loginLogs.entrySet().stream()
                .filter(entry -> entry.getValue().getHour() >= 10)
                .forEach(entry -> System.out.println(entry.getKey() + " 登录时间: " + entry.getValue()));
    }
}

这个例子展示了如何结合时间判断,用 Java 实例 – HashMap遍历 的方式实现业务逻辑,让代码更灵活。


写在最后

HashMap 遍历看似简单,但每种方式背后都有其适用场景和设计哲学。作为开发者,我们不仅要会用,更要理解“为什么用”。从 for-each 到 Stream,从迭代器到函数式编程,这些技术演进反映了 Java 语言的发展轨迹。

掌握 Java 实例 – HashMap遍历 的核心方法,不仅能提升代码质量,还能在面试和项目中游刃有余。建议你动手实践每一个例子,亲手写一遍,才能真正内化为自己的技能。

记住:编程不是记住语法,而是理解逻辑。多写、多试、多思考,你离高手就不远了。