资讯动态

# Java Map 实战:从授课安排增删改到世界杯冠军双向查询

发布时间:2026/10/29 11:02:47 来源:尧图企业网站定制
# Java Map 实战从授课安排增删改到世界杯冠军双向查询 上一篇写了 Map 的基础 API 和三种遍历。这篇直接上三个真实小案例老师授课安排的增删改查、按年份查世界杯冠军、按球队反查夺冠年份列表。重点不在写代码而在体会「什么场景该用 Map」以及「双向查询时怎么设计 Map」。 ## 案例一老师授课安排的增删改查 题目场景用 Map 存「老师 → 所授课程」要完成新增老师、修改老师课程、遍历输出、筛选教某门课的老师、统计某门课有几位老师。 java import java.util.HashMap; import java.util.Map; public class CourseSchedule { public static void main(String[] args) { // 键老师姓名值教授的课程 MapString, String courseMap new HashMap(); courseMap.put(张三, Java); courseMap.put(李四, JSP); courseMap.put(王五, CoreJava); courseMap.put(赵六, JSP); // (2) 新增一位老师 Allen 教 JDBC courseMap.put(Allen, JDBC); // (3) Lucy 改教 CoreJava —— put 同 key 即覆盖 courseMap.put(Lucy, CoreJava); // (4) 遍历输出所有老师及课程 System.out.println( 当前授课安排 ); for (Map.EntryString, String e : courseMap.entrySet()) { System.out.println(e.getKey() - e.getValue()); } // (5) 输出所有教 JSP 的老师 System.out.println(\n 教 JSP 的老师 ); for (Map.EntryString, String e : courseMap.entrySet()) { if (JSP.equals(e.getValue())) { System.out.println(e.getKey()); } } // (6) 统计教 CoreJava 和 JDBC 的老师人数 int coreJavaCount 0, jdbcCount 0; for (String course : courseMap.values()) { if (CoreJava.equals(course)) coreJavaCount; if (JDBC.equals(course)) jdbcCount; } System.out.println(\n教 CoreJava 的老师有 coreJavaCount 位); System.out.println(教 JDBC 的老师有 jdbcCount 位); } } 运行结果 当前授课安排 张三 - Java 李四 - JSP 王五 - CoreJava 赵六 - JSP Allen - JDBC Lucy - CoreJava 教 JSP 的老师 李四 赵六 教 CoreJava 的老师有 2 位 教 JDBC 的老师有 1 位 这里要记住两个操作直觉 - **修改课程**不是什么复杂方法就是 map.put(老师名, 新课程)——因为 key 唯一同 key 再 put 就是覆盖 - **按课程反查老师/统计人数**本质是遍历 values() 做条件过滤。value 不是键所以无法直接 get只能扫一遍。 ## 案例二输入年份查该年世界杯冠军 场景很常见存一张「年份 → 冠军球队」的对照表输入年份输出球队没举办过就提示。 java import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class WorldCupQuery { public static void main(String[] args) { // 历年世界杯冠军1930 年首届1942/1946 因二战停办 MapString, String championMap new HashMap(); championMap.put(1930, 乌拉圭); championMap.put(1934, 意大利); championMap.put(1938, 意大利); championMap.put(1950, 乌拉圭); championMap.put(1954, 西德); championMap.put(1958, 巴西); championMap.put(1962, 巴西); championMap.put(1966, 英格兰); championMap.put(1970, 巴西); championMap.put(1974, 西德); championMap.put(1978, 阿根廷); championMap.put(1982, 意大利); championMap.put(1986, 阿根廷); championMap.put(1990, 西德); championMap.put(1994, 巴西); championMap.put(1998, 法国); championMap.put(2002, 巴西); championMap.put(2006, 意大利); championMap.put(2010, 西班牙); championMap.put(2014, 德国); championMap.put(2018, 法国); championMap.put(2022, 阿根廷); Scanner sc new Scanner(System.in); System.out.print(请输入年份); String year sc.next(); String champion championMap.get(year); if (champion null) { System.out.println(year 年没有举办世界杯); } else { System.out.println(year 年世界杯冠军是 champion); } sc.close(); } } 测试 请输入年份2002 2002 年世界杯冠军是巴西 请输入年份1942 1942 年没有举办世界杯 这是最典型的「查找表」用法Map 就是一张查表字典key 是要查的条件value 是结果。 ## 案例三输入球队名反查所有夺冠年份 题目进阶输入「巴西」要输出它夺冠的所有年份 1958、1962、1970、1994、2002输入「荷兰」要输出「没有获得过世界杯」。 ### 思路一遍历正向 Map简单但慢 直接拿上一个 championMap遍历每个 entry只要 value 等于输入球队就收集 key java MapString, Integer result new HashMap(); // 仅示意收集逻辑 java.util.ListString years new java.util.ArrayList(); for (Map.EntryString, String e : championMap.entrySet()) { if (e.getValue().equals(巴西)) { years.add(e.getKey()); } } 数据量小的时候完全够用但每次反查都要扫整张表。 ### 思路二专门建一张反向 Map推荐 既然经常要「按球队查年份」干脆预先维护一张 球队 - 年份列表 的反向表查询时直接 get(球队名)O(1) java import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class WorldCupReverse { public static void main(String[] args) { // 正向表年份 - 球队 MapString, String yearToTeam new HashMap(); yearToTeam.put(1958, 巴西); yearToTeam.put(1962, 巴西); yearToTeam.put(1970, 巴西); yearToTeam.put(1994, 巴西); yearToTeam.put(2002, 巴西); yearToTeam.put(1930, 乌拉圭); yearToTeam.put(1950, 乌拉圭); yearToTeam.put(1978, 阿根廷); yearToTeam.put(1986, 阿根廷); yearToTeam.put(2022, 阿根廷); yearToTeam.put(1998, 法国); yearToTeam.put(2018, 法国); yearToTeam.put(1966, 英格兰); yearToTeam.put(2010, 西班牙); // 构建反向表球队 - 该队夺冠年份列表 MapString, ListString teamToYears new HashMap(); for (Map.EntryString, String e : yearToTeam.entrySet()) { String team e.getValue(); String year e.getKey(); // computeIfAbsent没有这个 key 就先放一个空 List再往里加 teamToYears.computeIfAbsent(team, k - new ArrayList()).add(year); } Scanner sc new Scanner(System.in); System.out.print(请输入球队名); String team sc.next(); ListString years teamToYears.get(team); if (years null || years.isEmpty()) { System.out.println(team 没有获得过世界杯); } else { System.out.print(team 夺冠年份); System.out.println(String.join(、, years)); } sc.close(); } } 测试 请输入球队名巴西 巴西 夺冠年份1958、1962、1970、1994、2002 请输入球队名荷兰 荷兰 没有获得过世界杯 这里有两个新东西值得记 - **反向 Map 的 value 用 List**因为一支球队可以对应多个年份一个 key 对应一个值不够值本身得是个集合 - **computeIfAbsent(key, k - new ArrayList())**一行搞定「没有就建空列表有就拿出来」比传统的 if (!containsKey) put 简洁很多。 ## 四、什么时候用哪种 Map 实现 | 实现类 | 特点 | 适用场景 | |---|---|---| | HashMap | 无序、查询快、key 允许一个 null | 默认首选大部分业务场景 | | LinkedHashMap | 按插入顺序排列 | 需要保持存取顺序如 LRU 缓存 | | TreeMap | 按 key 自然排序 | 需要按键排序输出 | | ConcurrentHashMap | 线程安全 | 多线程环境共享 Map | ## 五、实战踩坑总结 1. 反向查询频繁时预先建反向 Map别每次都全表遍历。 2. 一个 key 要对应多个值value 就用 List/Set别硬塞逗号拼接的字符串。 3. computeIfAbsent、getOrDefault、merge 这些新方法能少写很多 if-else值得熟悉。 4. 用中文/英文做 key 时注意 equals 比较常量写前面JSP.equals(value)避免 value 为 null 时空指针。 ## 写在最后 经过这几个案例我最大的体会是**Map 不只是一个容器而是一种「索引思维」**。正向查快、反向查慢那我就为反向也建一个索引一个 key 要对应多条记录那值就用集合。把这点想通Map 在实际项目里怎么用就清楚了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑