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
相关产品推荐
相关产品推荐

