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())
更容易)。修复了它。就这样。