Java中基于文本文件每行首元素创建对应对象时仅解析第一行的问题求助
问题分析与解决方案
你的代码只处理第一行的问题,根源在于Scanner分隔符的设置没有考虑换行符,导致第一行末尾的内容和第二行的标识被混在了一起,无法正确匹配对象类型。
为什么原来的代码失效?
当你执行myFile.useDelimiter(",")时,Scanner只会将逗号作为分隔符,换行符会被当作普通字符保留在元素中。举个例子,你的文件内容实际是:
ul,1,gg,0,33.0\nsl,2,hh,0,44.0
按照逗号分割后,元素序列会变成:"ul"、"1"、"gg"、"0"、"33.0\nsl"、"2"、"hh"、"0"、"44.0"
当处理完第一行的5个元素后,下一个myFile.next()会拿到"33.0\nsl",这个字符串既不等于"sl"也不等于"ul",自然不会进入任何对象创建分支,后续的元素也无法正确匹配类型,最终只有第一行被处理。
修复后的代码方案
推荐采用逐行读取+分割元素的方式,这样能保证每行的内容独立处理,避免换行符干扰:
Scanner myFile = new Scanner(fr); while (myFile.hasNextLine()) { // 读取完整一行内容 String line = myFile.nextLine(); // 按逗号分割每行的元素 String[] parts = line.split(","); // 跳过格式错误的行(比如元素数量不对) if (parts.length != 5) { System.out.println("Skipping invalid line: " + line); continue; } // 去除前后空格,避免因空格导致匹配失败 String type = parts[0].trim(); if ("sl".equals(type)) { StrongLanding sl = new StrongLanding(); sl.setLandingId(Integer.parseInt(parts[1].trim())); sl.setLandingDesc(parts[2].trim()); sl.setNumLandings(Integer.parseInt(parts[3].trim())); sl.setCost(Double.parseDouble(parts[4].trim())); landings.add(sl); } else if ("ul".equals(type)) { UltimateLanding ul = new UltimateLanding(); ul.setLandingId(Integer.parseInt(parts[1].trim())); ul.setLandingDesc(parts[2].trim()); ul.setNumLandings(Integer.parseInt(parts[3].trim())); ul.setCost(Double.parseDouble(parts[4].trim())); landings.add(ul); } }
额外优化建议
- 使用
"sl".equals(type)而非type.equals("sl"):可以避免当type为null时抛出NullPointerException。 - 增加格式校验:比如对数值类型的转换增加
try-catch块,避免因文件格式错误导致程序崩溃。 - 自动管理资源:可以使用try-with-resources语法,让JVM自动关闭Scanner和文件流,避免资源泄漏:
try (Scanner myFile = new Scanner(fr)) { // 循环处理逻辑 }
内容的提问来源于stack exchange,提问作者JakeStillone
相关产品推荐
相关产品推荐

