Java中的While循环赢得了';t在文档的最后一行执行操作
我有一个文本文档,如下所示:Java中的While循环赢得了';t在文档的最后一行执行操作,java,while-loop,Java,While Loop,我有一个文本文档,如下所示: 2 2 1 4 2 8 2 4 1 4 2 8 2 6 1 4 2 8 while ((line = br.readLine()) != null) { doSomethingWith(line); } 我想找到第二列(2,4,6)中所有数字的平均值。我写了一个while循环,我认为应该这样做。totalVal是所有加在一起的数字的总值,totalNum是数字的总数 String line = data.nextLine();// read one lin
2 2 1 4 2 8
2 4 1 4 2 8
2 6 1 4 2 8
while ((line = br.readLine()) != null) {
doSomethingWith(line);
}
我想找到第二列(2,4,6)中所有数字的平均值。我写了一个while循环,我认为应该这样做。totalVal是所有加在一起的数字的总值,totalNum是数字的总数
String line = data.nextLine();// read one line into a String
while (data.hasNextLine()) {
String[] field = line.split(" ");
totalVal += Double.parseDouble(field[1]);
totalNums += 1;
line = data.nextLine();
}
System.out.println(totalVal / totalNums);
问题是,我得到的答案返回的值是3,这意味着它只取文档中前两行文本的平均值,而忽略了第三行
有人能告诉我如何更改循环,使其在文本的第三行中也添加值吗?不清楚为什么在循环之前阅读一行 如果在循环的第一步读取一行,那么所有行都将被正确处理
while (data.hasNextLine()) {
String line = data.nextLine();
String[] field = line.split(" ");
totalVal += Double.parseDouble(field[1]);
totalNums += 1;
}
当您位于前最后一行时,使用
line=data.nextLine()检索最后一行
然后立即检查while
循环中的data.hasNextLine()
。由于到达最后一行,因此返回false
,然后退出循环
将代码更改为:
while (data.hasNextLine()) {
String line = data.nextLine();
String[] field = line.split(" ");
totalVal += Double.parseDouble(field[1]);
totalNums += 1;
}
这首先检查是否有下一行,然后获取它
现在,超级Java 8一行程序用于:
double average = Files.lines(Paths.get(file))
.mapToDouble(l -> Double.parseDouble(l.split(" ")[1]))
.average().orElse(0);
相信JVM:阅读第三行之后,就没有下一行了。它停下来是因为你叫它停下来 试着这样做:
package cruft;
import java.util.Scanner;
/**
* LoopDemo made to work
* @author Michael
* @link https://stackoverflow.com/questions/32810613/while-loop-in-java-wont-perform-action-on-last-line-of-document/32810646?noredirect=1#comment53458064_32810646
* @since 9/27/2015 1:27 PM
*/
public class LoopDemo {
public static void main(String[] args) {
try {
Scanner data = new Scanner(LoopDemo.class.getResourceAsStream("/LoopDemo.dat"));
double totalVal = 0.0;
int totalNums = 0;
String line;
while (data.hasNextLine()) {
line = data.nextLine();
String[] field = line.split("\\s+");
totalVal += Double.parseDouble(field[1]);
totalNums += 1;
}
System.out.println(totalVal / totalNums);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果您在末尾打印出
行
,您会发现最后一行在那里。您捕获了最后一行,清空文件,然后在清空文件后检查是否还有其他行。你要么这样做
while(data.hasNextLine())
{
line = nextLine();
// ...stuff...
}
然后移除循环外部的
line=nextLine() 您可以使用BufferedReader(br)读取文档的所有行,如下所示:
2 2 1 4 2 8
2 4 1 4 2 8
2 6 1 4 2 8
while ((line = br.readLine()) != null) {
doSomethingWith(line);
}
难怪,您正在读取一行(在循环中),然后检查之后是否还有另一行,然后处理该读取行。因为最后一行后面没有行,所以你忽略了它。哎呀,我搞错了。它应该是while(true)
。让我来修。是的,那好多了。您可以清楚地看到循环何时停止,而不必检查循环体中的信息。虽然这是事实,但基于OP使用了nextLine()
这一事实,我们应该假设data
是Scanner
不是BufferedReader
和Scanner\nextLine()
不返回null
,但在缺少下一行的情况下抛出NoTouchElementException
。Scanner为我们提供了很好的hasNextLine()
方法,这样我们就可以在((line=br.readLine())!=null)
习惯用法时避免该异常和。@Pshemo感谢您的提示。我只是想展示另一种选择,因为我没有读到他被迫使用Scanner
。我没有说OP被迫使用Scanner,但一般来说,使用它和它的next…
方法比处理null
s更容易。因此,我不会因为你的答案不正确而否定你的答案(因为正如你提到的那样,它解决了问题),但我也不能否定你的答案,因为它使用的是旧的,可能更容易混淆的方式(IMO,而(scanner.hasNextLine())
更容易)。修复了它。就这样。