
本文详解如何在java中安全读取文本文件中的整数,自动过滤重复值与非法输入,并准确填充固定长度数组,重点修复因变量作用域导致的去重逻辑失效问题。
本文详解如何在java中安全读取文本文件中的整数,自动过滤重复值与非法输入,并准确填充固定长度数组,重点修复因变量作用域导致的去重逻辑失效问题。
在Java中从文件读取整数并去重填充数组是一个常见但易出错的任务。原始代码的核心缺陷在于布尔标志 ID 的声明位置不当:它被定义为方法级变量(boolean ID = false;),在循环中未重置,导致一旦某次检测到重复值后,ID 保持 true 状态,后续所有合法数字均被误判为重复,从而严重漏填——这正是仅成功处理11/20个数字的根本原因。
关键修复在于将 ID 的声明移入 while 循环体内,确保每次处理新数字前其初始值均为 false:
private static int read(String inFileName, int[] list) {
int size = 0;
Scanner inFile = null;
int trash = 0, unique = 0, dupe = 0, lineCount = 0;
try {
inFile = new Scanner(new File(inFileName));
while (inFile.hasNext()) {
lineCount++;
boolean isDuplicate = false; // ✅ 每轮重置标志位
try {
int val = inFile.nextInt();
if (val < 0) {
trash++;
continue;
}
// 遍历已存元素检查重复
for (int i = 0; i < size; i++) {
if (list[i] == val) {
isDuplicate = true;
dupe++;
break; // ✅ 找到即退出,提升效率
}
}
// 仅当非重复且数组未满时添加
if (!isDuplicate && size < list.length) {
list[size] = val;
size++;
unique++;
}
} catch (InputMismatchException e) {
trash++;
inFile.nextLine(); // 清除错误行,避免死循环
}
}
System.out.printf("Lines: %d, Unique: %d, Duplicates: %d, Invalid: %d%n",
lineCount, unique, dupe, trash);
} catch (FileNotFoundException e) {
System.err.println("Error: File '" + inFileName + "' not found.");
} finally {
if (inFile != null) inFile.close(); // ✅ 始终关闭资源
}
return size;
}重要注意事项与优化建议:
-
资源管理:务必在 finally 块中关闭 Scanner,防止文件句柄泄漏;现代写法推荐使用 try-with-resources(JDK 7+):
立即学习“Java免费学习笔记(深入)”;
try (Scanner inFile = new Scanner(new File(inFileName))) { // ... 读取逻辑 } 性能考量:当前 O(n²) 查重适用于小数据集(如题中20个数)。若数据量增大,应改用 HashSet<Integer> 缓存已见值,将查重降为 O(1) 平均时间复杂度。
边界安全:size < list.length 判断必须保留,避免 ArrayIndexOutOfBoundsException;若需严格保证全部唯一值,建议先用动态集合(如 ArrayList)收集,再截取或复制到目标数组。
输入健壮性:inFile.nextLine() 在捕获 InputMismatchException 后清除整行,防止因非数字字符(如空行、字母)导致 hasNext() 无限返回 true。
综上,正确的作用域控制是此类逻辑题的关键突破口。通过将状态变量置于最小必要作用域内,并辅以资源管理与边界防护,即可稳定、可维护地完成文件去重填充任务。










