在Java里如何完成学生选课系统_Java集合与对象实战说明

发布时间 - 2026-02-03 00:00:00    点击率:
应使用HashMap管理课程与学生映射,指定初始容量;用computeIfAbsent安全添加学生;查重选课用HashSet(需正确重写equals/hashCode);排序推荐用TreeSet配自定义Comparator;按时间序展示用LinkedHashMap(插入序)。

如何用 HashMap 管理课程与学生映射关系

学生选课本质是“一对多”关系:一门课对应多个学生,一个学生可选多门课。直接用 HashMap> 最直观——课程编号作 key,学生列表作 value。

注意别用 ArrayList 存所有选课记录再遍历查找,性能差(O(n));也别把学生 ID 拼成字符串存进 map,丧失对象语义和类型安全。

  • HashMap 初始化时建议指定初始容量,比如预估 50 门课,就写 new HashMap(64),避免频繁扩容
  • 添加选课时,先 computeIfAbsent 获取或创建对应课程的 ArrayList,再 add 学生对象,避免空指针
  • 不要在遍历 values() 时直接修改某个 List,会触发 ConcurrentModificationException;如需动态删选课,改用 Iterator 或收集待删项后批量处理

为什么 HashSetArrayList 更适合查重选课

学生不能重复选择同一门课,校验逻辑必须快且可靠。用 ArrayList courseIds 存已选课号,每次 contains() 是 O(n);换成 HashSet,平均 O(1),且自动去重。

关键前提是:Student 类必须正确重写 hashCode()equals(),否则用 HashSet 判断“同一学生”会失效。

  • 如果用学号 id 唯一标识学生,equals() 只比较 id 字段,hashCode() 基于 id 计算
  • 别在 HashSet 里存可变对象(比如未设 final 的字段),一旦修改影响 hash 值,对象可能“丢失”——再也 contains() 不到
  • 调试时发现 set.contains(x) 返回 false,先打印 x.hashCode() 和集合中同类对象的 hash 值,确认是否重写有误

TreeSet 实现按学分排序的课程推荐

系统要给学生推荐“学分从高到低”的可选课程,需要天然有序的集合。TreeSet 能自动排序,但必须明确告诉它怎么比。

别直接让 Course 实现 Comparable 并固定按学分排——这样后续想按名称或开课时间排就冲突了。更灵活的做法是传入自定义 Comparator

new TreeSet<>((a, b) -> Integer.compare(b.getCredit(), a.getCredit()))

这样既复用 TreeSet 的 O(log n) 插入/查询,又不污染业务类。

  • TreeSet 不允许 null 元素,插入前确保 Course 对象非空
  • 如果推荐逻辑需支持多种排序策略(如“学分优先,相同学分按名称升序”),用链式比较:Comparator.comparing(Course::getCredit).reversed().thenComparing(Course::getName)
  • 注意 TreeSetsubSetheadSet 等方法返回的是原 set 的视图,修改会影响原集合

什么时候该用 LinkedHashMap 记录选课时间顺序

学生选课有先后,系统需展示“最近选的 5 门课”。HashMap 不保证顺序,TreeMap 按 key 排序(不是时间),这时 LinkedHashMap 是唯一轻量解法——它按插入顺序迭代。

但要注意:默认构造的 LinkedHashMap 是插入序;若传入 true 构造参数(即

new LinkedHashMap(16, 0.75f, true)),则变成访问序(LRU 缓存逻辑),不适合此处。

  • 要限制只存最近 N 条,得手动在 put 后检查 size,超限时调用 removeFirstEntry()(Java 21+)或用迭代器删头节点
  • 别把时间戳当 key 存进 LinkedHashMap——时间可能重复,导致覆盖;应把 Course 对象作 value,key 仍用课程 ID,靠链表维护顺序
  • 序列化 LinkedHashMap 时顺序保留,但反序列化后仍是插入序,这点比 TreeMap 更可控
实际写的时候,最容易漏的是 StudentCourseequals/hashCode 实现细节,以及 LinkedHashMap 构造参数里那个布尔值的意义——错一位,整个顺序逻辑就崩了。


# java  # ai  # 为什么  # red  # String  # NULL  # 字符串  # 指针  # 空指针  # map  # 对象  # 重写  # 的是  # 遍历  # 自定义  # 可选  # 链式  # 一门  # 别把  # 升序  # 迭代 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何快速生成高效建站系统源代码?  如何实现javascript表单验证_正则表达式有哪些实用技巧  Python函数文档自动校验_规范解析【教程】  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  教你用AI将一段旋律扩展成一首完整的曲子  如何在搬瓦工VPS快速搭建网站?  长沙企业网站制作哪家好,长沙水业集团官方网站?  使用spring连接及操作mongodb3.0实例  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  高性能网站服务器配置指南:安全稳定与高效建站核心方案  Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案  Python结构化数据采集_字段抽取解析【教程】  Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  如何为不同团队 ID 动态生成多个非值班状态按钮  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何用腾讯建站主机快速创建免费网站?  深入理解Android中的xmlns:tools属性  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  Laravel如何使用Collections进行数据处理?(实用方法示例)  微信小程序 require机制详解及实例代码  如何在万网自助建站平台快速创建网站?  历史网站制作软件,华为如何找回被删除的网站?  ,交易猫的商品怎么发布到网站上去?  Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧  Bootstrap CSS布局之列表  北京的网站制作公司有哪些,哪个视频网站最好?  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  lovemo网页版地址 lovemo官网手机登录  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  如何在建站之星绑定自定义域名?  Swift中switch语句区间和元组模式匹配  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  如何在宝塔面板中修改默认建站目录?  Laravel怎么上传文件_Laravel图片上传及存储配置  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  企业网站制作这些问题要关注  韩国服务器如何优化跨境访问实现高效连接?  如何在橙子建站中快速调整背景颜色?  香港服务器如何优化才能显著提升网站加载速度?  如何彻底删除建站之星生成的Banner?  Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  如何在不使用负向后查找的情况下匹配特定条件前的换行符  如何基于云服务器快速搭建个人网站?  Linux网络带宽限制_tc配置实践解析【教程】  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解