Java: 没有 forEach,逐行处理流?

Java: Processing Stream line by line without forEach?

我是 Java 的新手,第一次试用 Streams。

我有一个很大的输入文件,其中每一行都有一个字符串,例如:

cart
dumpster
apple
cherry
tank
laptop
...

我正在尝试以流的形式读取文件并对数据进行一些分析。例如,要计算特定字符串的所有出现次数,我可能会想这样做:

Stream<String> lines = Files.lines(Path.of("/path/to/input/file.txt"));
int count = 0;

lines.forEach((line) => {
    if (line.equals("tank")) {
        count++;
    }
});

但是,Java 不允许在 lambda 中更改变量。

我不确定是否有另一种方法可以逐行读取流。我该如何正确执行此操作?

您不需要流外部的变量。如果你有一个非常大的文件要计算,long 将是首选

long tanks = lines
    .filter(s -> s.equals("tank"))
    .count();

要使用常规循环迭代流,您可以从流中获取迭代器并使用 for 循环:

Iterable<String> iterable = lines::iterator;
for (String line : iterable) {
    if (line.equals("tank")) {
         ++count;
    }
}

但在这种特殊情况下,您可以只使用流的 count 方法:

int count = (int) lines.filter("tank"::equals).count();

您可以逐行读取文件,每行都有一个流:

    try (Stream<String> lines = Files.lines(Path.of("/path/to/input/file.txt"))) {
        list = stream
                .filter(line -> !line.startsWith("abc"))
                .map(String::toUpperCase)
                .collect(Collectors.toList());

    } catch (IOException e) {
        e.printStackTrace();
    }