学习前提

理解类、对象与方法;已能遍历数组。

本课完成后你能做什么

选择集合结构,并生成稳定的统计结果。

先理解机制

List保存有序元素且允许重复;Map把唯一键映射到值。泛型Map<String,Integer>让编译器检查键和值类型,减少运行时强制转换错误。

HashMap不保证遍历顺序。展示报表时把entrySet复制到列表,再明确按键排序。稳定输出有利于阅读和测试,不能依赖某次运行恰好的顺序。

merge在键缺失时放入初始值,在键存在时调用合并函数。这里Integer::sum表达重复课程累加。List.of返回不可修改列表,不能向它add。

可运行示例

使用JDK 21。将代码保存为Main.java,在独立练习目录执行 javac -encoding UTF-8 Main.java,再执行 java Main。每章独立运行,不把多个public Main类放进同一文件。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        List<String> courses = List.of("Python", "Java", "Python");
        Map<String, Integer> counts = new HashMap<>();
        for (String course : courses) counts.merge(course, 1, Integer::sum);
        List<Map.Entry<String, Integer>> entries = new ArrayList<>(counts.entrySet());
        entries.sort(Map.Entry.comparingByKey());
        for (var entry : entries) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

推演与验证

Java按字母排序先输出1,Python输出2。原列表保留重复项,Map仅保留两个键。

常见错误与边界

不要一边遍历普通集合一边随意结构性修改它。大型计数可能超过Integer范围,届时应调整数据类型与约束。

动手练习

加入SQL两次,再按次数降序、课程名升序排序。

参考解法与理由

比较器先比较b.getValue()与a.getValue(),相同再比较a.getKey()与b.getKey();用Integer.compare避免减法溢出。结果Python:2、SQL:2、Java:1。

进一步阅读