Scanner读取10万条数据抛出InputMismatchException求助
问题排查:Scanner处理10万条数据时抛出InputMismatchException
问题描述
输入几千条数据时程序无报错,但数据量增至100000条时,抛出异常:
Exception in thread "main" java.util.InputMismatchException,怀疑是Scanner的问题,请求排查。
程序代码
import java.math.BigInteger; import java.util.*; class Work { public long end; public long money; Work(long end, long money){ this.end = end; this.money = money; } } public class TanXin { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); List<Work> works = new ArrayList<>(); for (int i = 0; i < n; i++) { long end = scanner.nextLong(); long money = scanner.nextLong(); works.add(new Work(end ,money)); } Collections.sort(works, new Comparator<Work>() { @Override public int compare(Work o1, Work o2) { return Long.compare(o1.end, o2.end); } }); scanner.nextLine(); long curEnd = works.get(0).end; long money = works.get(0).money; BigInteger result = BigInteger.valueOf(0); for (int i = 1; i < works.size(); i++) { Work work = works.get(i); if(work.end == curEnd){ money = Math.max(money, work.money); } else { result=result.add(BigInteger.valueOf(money)); money = work.money; curEnd = work.end; } } result=result.add(BigInteger.valueOf(money)); System.out.println(result); } }
输入示例
100000 801615855 349230664 887145852 256709348 543490607 406712523 290306792 866994656 761434274 614622174 523543132 477488683 416651127 515580101 610336950 152185241 337713494 547698342 6453239 251894056 17161871 278487265 309123183 826630026 22171935 97670396 937046566 551871611 338360787 511206428 234499030 12274630 999066863 377262036 498450141 907352279 699130053 40056368 341503872 598356413 92329093 58969313 839293680 912223354 435852220 370051435 328226392 703616380 84394712 320189993 89139302 692379179 668921100 37915667 750500527 980565603 951214595 443240740 342283327 733767608 674959282 407118651 114057416 595985258 908001458 748864346 406064066 170499053
排查分析
- 输入数据格式问题:
InputMismatchException本质是Scanner读取的内容与预期类型不匹配,大概率是10万条数据中存在非法内容——比如非数字字符、超出long范围的数值(long取值范围为-9223372036854775808至9223372036854775807)。 - Scanner性能瓶颈:Scanner在处理超大量输入时,默认的缓冲区机制可能出现读取不完整的情况,导致某一行数据被截断,后续读取时触发类型不匹配异常。
- 代码冗余操作:读取完所有数据后调用的
scanner.nextLine();属于冗余操作,若输入末尾存在空行或残留字符,可能干扰后续逻辑,但不是触发异常的核心原因。
解决方案
1. 校验输入数据完整性
检查10万条数据的每一行,确保两个数值均为合法的long类型,无格式错误、非数字字符或超出范围的数值。
2. 替换为高效的读取方式
改用BufferedReader配合StringTokenizer处理大输入,比Scanner效率更高、稳定性更强,避免缓冲区问题:
import java.math.BigInteger; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; class Work { public long end; public long money; Work(long end, long money){ this.end = end; this.money = money; } } public class TanXin { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); List<Work> works = new ArrayList<>(); StringTokenizer st; for (int i = 0; i < n; i++) { String line = br.readLine(); st = new StringTokenizer(line); long end = Long.parseLong(st.nextToken()); long money = Long.parseLong(st.nextToken()); works.add(new Work(end, money)); } Collections.sort(works, Comparator.comparingLong(o -> o.end)); long curEnd = works.get(0).end; long money = works.get(0).money; BigInteger result = BigInteger.ZERO; for (int i = 1; i < works.size(); i++) { Work work = works.get(i); if(work.end == curEnd){ money = Math.max(money, work.money); } else { result = result.add(BigInteger.valueOf(money)); money = work.money; curEnd = work.end; } } result = result.add(BigInteger.valueOf(money)); System.out.println(result); br.close(); } }
3. 添加异常定位日志
在读取数据时加入异常捕获,打印出错的行号和内容,快速定位问题数据:
for (int i = 0; i < n; i++) { try { String line = br.readLine(); st = new StringTokenizer(line); long end = Long.parseLong(st.nextToken()); long money = Long.parseLong(st.nextToken()); works.add(new Work(end, money)); } catch (NumberFormatException e) { System.err.println("第" + (i+1) + "行数据格式错误:" + br.readLine()); e.printStackTrace(); return; } }
内容的提问来源于stack exchange,提问作者little little
相关产品推荐
相关产品推荐

