Java中BufferedReader逐行读文件时判断isEmpty为何结果不同?
文件读取结果差异的原因分析
核心问题
你写的方式#2存在循环逻辑错误,导致读取到第一个空行后直接终止,后续所有行都没被读取,这是和#1、#3结果差异的根本原因。
三种读取逻辑的对比
方式#1(流式读取)
reader.lines().filter(l -> !l.isEmpty()).collect(Collectors.toSet());
- 行为:读取文件的全部行,仅过滤掉空行,不会因为空行停止读取,所有非空行都会被收集到Set中。
方式#2(错误的终止逻辑)
while ((row = reader.readLine()) != null && !row.isEmpty()) { readUsingNonEmpty.add(row); }
- 行为:
&&是短路逻辑运算符——只要读取到空行,!row.isEmpty()就会返回false,整个循环条件直接不成立,循环立即终止。这意味着文件中第一个空行之后的所有内容,都不会被读取和处理。
方式#3(全量读取)
while ((row1 = reader.readLine()) != null) { if (row1.isEmpty()) { counter += 1; } readNonCheckingNonEmpty.add(row1); }
- 行为:读取文件的全部行,遇到空行仅做计数,不会终止循环,所有行(包括空行)都会被加入Set。
结合你的运行结果验证
从输出的Counter: 2可以确认,文件中确实存在2个空行。方式#2读取到第一个空行就停止了,导致后续的7526 - 5498 = 2028行(包含1个空行和2027个有效ID)全部被遗漏,这正好对应Difference in size: 2028的结果。
方式#1会跳过这2个空行,所以最终Set的大小是总行数减去空行数,和你的Size readUsingCollect: 7525结果吻合。
修正方式#2的代码
要让方式#2和#1的结果一致,需要把空行判断移到循环体内部,避免终止循环:
Set<String> readUsingNonEmpty = new HashSet<>(); while ((row = reader.readLine()) != null) { if (!row.isEmpty()) { // 空行跳过,但继续读取后续内容 readUsingNonEmpty.add(row); } }
内容的提问来源于stack exchange,提问作者toy
相关产品推荐
相关产品推荐

