学习前提
理解类、对象与方法;已能遍历数组。
本课完成后你能做什么
选择集合结构,并生成稳定的统计结果。
先理解机制
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。