You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java程序读取电影文件计算最值输出null问题求助

分析你的Java电影数据查询程序null输出问题

我帮你排查了代码里的几个关键问题,这些都是导致所有查询项输出null的核心原因:

1. Switch Case分支缺失Break,导致比较器被错误覆盖

看你produceOutput方法里的switch逻辑,ratingPercentage分支没有加break,这会导致代码执行完该分支后,立刻进入下一个ratingScore分支,直接覆盖掉你刚设置的比较器。如果后续优先队列依赖错误的比较器,或者列表为空,就会返回null:

case"ratingPercentage":
 cp = new Comparator<Movie>() {
 public int compare(Movie m1, Movie m2) {
 return (int) (m2.ratingPercentage-m1.ratingPercentage);
 }
 };
// 这里缺少break!会继续执行ratingScore分支
case"ratingScore":
 cp = new Comparator<Movie>() {
 public int compare(Movie m1, Movie m2) {
 return (int) (m2.averageRating-m1.averageRating);
 }
 };
 break;

修复方案:给ratingPercentage分支添加break,同时用更安全的类型比较方法避免溢出:

case"ratingPercentage":
 cp = new Comparator<Movie>() {
 public int compare(Movie m1, Movie m2) {
 return Long.compare(m2.ratingPercentage, m1.ratingPercentage);
 }
 };
break; // 新增break
case"ratingScore":
 cp = new Comparator<Movie>() {
 public int compare(Movie m1, Movie m2) {
 return Float.compare(m2.averageRating, m1.averageRating);
 }
 };
 break;

另外注意:用户输入的是views(小写v),但代码里是case"Views"(大写V),会匹配失败进入default分支,要改成case"views"统一大小写。

2. pickMin方法存在致命递归错误

你的pickMin方法有两个严重问题:

  • 当m == null时,递归调用return pickMin(m);会直接导致栈溢出,永远无法退出
  • 匿名比较器里的return(c.compare(m2, m1));,这里的c就是当前比较器本身,会无限递归调用自己的compare方法

修复后的pickMin方法:

@Override
public Movie pickMin(Comparator<Movie> m) {
 if(m == null) {
 System.out.println("Reversing default comparable is not implemented");
 return null; // 停止递归,直接返回null
 }else{
 // 用原比较器的反向逻辑创建新比较器
 Comparator<Movie> reverseComp = m.reversed(); // Java 8+可用,简洁安全
 MyPriorityQueue<Movie> pq = new MyPriorityQueue<>(movies, reverseComp);
 Movie m2 = pq.poll();
 System.out.println("The lowest is " + m2);
 return m2;
 }
}

3. 核心根源:movies列表为空

输出null最可能的原因是你的movies列表根本没有读取到任何数据,导致优先队列poll()返回null。需要检查readInputFile的读取逻辑:

  • 文件路径问题:确认project 2.txt在程序工作目录下,或者提供完整文件路径
  • 分隔符匹配问题:你用line.split("\t")按制表符分割,但如果文件里是空格/逗号分隔,会导致elements.length !=5,直接跳过所有行
  • 反转字符串的逻辑:如果文件第一个字段不是反转的数字,Long.parseLong会抛出NumberFormatException,但你没捕获这个异常,会导致该行被跳过,甚至程序终止

调试建议:在readInputFile里添加日志,排查读取过程:

while(input.hasNextLine()) {
 String line = input.nextLine();
 System.out.println("读取到行:" + line);
 String[] elements = line.split("\t");
 System.out.println("分割后元素数量:" + elements.length);
 if(elements.length != 5) {
 System.out.println("跳过无效行:" + line);
 continue;
 }
 try {
 String tmp = (new StringBuilder(elements[0])).reverse().toString();
 long ratingPercentage = Long.parseLong(tmp.trim(),10);
 int StudThatSeenMov = Integer.parseInt(elements[1].trim());
 float AverageRating = Float.parseFloat(elements[2].trim());
 int movieReleaseYear = Integer.parseInt(elements[4].trim());
 Movie m = new Movie(ratingPercentage,StudThatSeenMov,AverageRating,elements[3],movieReleaseYear);
 lmovie.add(m);
 System.out.println("成功添加电影:" + m);
 } catch (NumberFormatException e) {
 System.out.println("解析数字失败:" + line);
 e.printStackTrace();
 }
}

最后一步:检查MyPriorityQueue实现

确保你的MyPriorityQueue类能正确根据传入的比较器排序,并且poll()方法能返回队列的首元素(最大/最小)。如果这个类的实现有问题,也会导致返回null。

内容的提问来源于stack exchange,提问作者l.m.m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:29:44