有一种方法可以使用标准Java 8 Stream API将文件内容分割并处理为
n
大小的块。您可以使用
Collectors.groupingBy()
将文件内容分成块,您可以将它们收集为
Collection<List<String>>
或者在收集所有行时应用一些处理(例如,您可以将它们连接到单个字符串中)。
请看以下示例:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ReadFileWithStream {
public static void main(String[] args) throws IOException {
final Path path = Paths.get(ReadFileWithStream.class.getResource("/input.txt").toURI());
final AtomicInteger counter = new AtomicInteger(0);
final int size = 4;
final Collection<List<String>> partitioned = Files.lines(path)
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size))
.values();
partitioned.forEach(System.out::println);
}
}
我的输入文件包含一些数字(每行一个),当我运行以下代码时,我会得到类似于:
[0, 0, 0, 2]
[0, -3, 2, 0]
[1, -3, -8, 0]
[2, -12, -11, -11]
[-8, -1, -8, 0]
[2, -1, 2, -1]
... and so on
Collectors.groupingBy()
还允许我使用不同的下游收集器。默认情况下会使用 Collectors.toList()
,因此我的结果被累积到一个 List<String>
中,并且我得到一个 Collection<List<String>>
作为最终结果。
假设我想读取 4 个元素并对每个元素中的所有数字求和。在这种情况下,我将使用 Collectors.summingInt()
作为我的下游函数,返回的结果是 Collection<Integer>
:
final Collection<Integer> partitioned = Files.lines(path)
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size, Collectors.summingInt(Integer::valueOf)))
.values()
输出:
2
-1
-10
-32
-17
2
-11
-49
... and so on
Collectors.groupingBy()
返回一个按照特定键分组的值的map。因此,最后我们调用
Map.values()
来获取此map中包含的值的集合。
希望这能帮到你。