Java 8从CSV过滤流行,但保留第一行

问题描述 投票:1回答:2

我想从CSV文件中删除包含错误日期的行。在此过程中,CSV文件应保留标题行。我想使用Java 8流执行所有这些操作。

起初,我想到了:

try (Stream<String> linesUnfiltered = Files.lines(f.toPath(), StandardCharsets.UTF_8)) {
    Stream<String> firstLine = linesUnfiltered.limit(1);
    Stream<String> linesFiltered = linesUnfiltered
            .filter(e -> e.contains(sdfFileContent.format(fileDate)));
    Stream<String> result = Stream.concat(firstLine, linesFiltered);
    Files.write(f.toPath(), (Iterable<String>) result::iterator);
}

但是由于重用了java.lang.IllegalStateException: stream has already been operated upon or closed,因此会引发异常linesUnfiltered。 Web上的建议是使用Supplier<Stream<String>>,但是我的理解是供应商会为每个supplier.get()调用读取文件,这不是很有效。

这就是为什么我要问是否还有另一种方法比这更有效?我非常确定,应该可以在同一流上执行两个操作...

编辑:

它是NOT重复项,因为不应删除第一项。仅应将其从过滤过程中排除,但仍可在结果流中使用]

java java-8 stream
2个回答
1
投票

您可以使用阅读器并调用其readLine方法来使用标头,然后根据lines()的结果进行过滤(在使用了同一阅读器的第一行之后:]]

try (BufferedReader reader = Files.newBufferedReader(f.toPath(), StandardCharsets.UTF_8)) {

    Stream<String> firstLine = Stream.of(reader.readLine());
    Stream<String> linesFiltered = reader.lines()
            .filter(e -> e.contains(sdfFileContent.format(fileDate)));
    Stream<String> result = Stream.concat(firstLine, restOflines);

    ...

0
投票

您可以将Stream转换为Iterator,采用第一个元素,然后再转换回。

© www.soinside.com 2019 - 2024. All rights reserved.