在Java 8中使用Stream API解析文件

本文展示了如何在Java 8中利用Stream API轻松解析CSV文件。通过BufferedReader读取文件,分别实现了读取文件头和所有记录的方法。读取头的方法获取第一行并按分隔符分割,而读取记录的方法跳过头行并处理每行数据。测试案例验证了正确读取文件内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 8中到处都有流。只需四处看看,可以肯定地找到它们。 它也适用于java.io.BufferedReader 。 使用Stream API在Java 8中解析文件非常容易。

我有一个要读取的CSV文件。 下面的例子:

  1. username;visited

  2. jdoe;10

  3. kolorobot;4

我的阅读器的一项合同是提供标头作为字符串列表,并提供所有记录作为字符串列表。 我的阅读器接受java.io.Reader作为阅读源。

我将从阅读标题开始。 读取标头的算法如下:

  • 打开阅读源,
  • 获取第一行并进行解析,
  • 用分隔符分割线,
  • 获取第一行并进行解析,
  • 将行转换为字符串列表并返回。

并执行:

class CsvReader {
 
    private static final String SEPARATOR = ";";
 
    private final Reader source;
 
    CsvReader(Reader source) {
        this(source);
    }
    List<String> readHeader() {
        try (BufferedReader reader = new BufferedReader(source)) {
            return reader.lines()
                    .findFirst()
                    .map(line -> Arrays.asList(line.split(SEPARATOR)))
                    .get();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }    
}

很简单。 不言自明。 同样,我创建了一种读取所有记录的方法。 读取记录的算法如下:

  • 打开阅读源,
  • 跳过第一行,
  • 用分隔符分割线,
  • 在将行映射到字符串列表的每一行上应用一个映射器。

并执行:

class CsvReader {
    List<List<String>> readRecords() {
        try (BufferedReader reader = new BufferedReader(source)) {
            return reader.lines()
                    .substream(1)
                    .map(line -> Arrays.asList(line.split(separator)))
                    .collect(Collectors.toList());
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }  
}

这里没什么好看的。 您可能会注意到,这两种方法中的映射器完全相同。 实际上,可以很容易地将其提取为变量:

    Function<String, List<String>> mapper 
        = line -> Arrays.asList(line.split(separator));

最后,我创建了一个简单的测试。

    public class CsvReaderTest {
     
        @Test
        public void readsHeader() {
            CsvReader csvReader = createCsvReader();
            List<String> header = csvReader.readHeader();
            assertThat(header)
                    .contains("username")
                    .contains("visited")
                    .hasSize(2);
        }
     
        @Test
        public void readsRecords() {
            CsvReader csvReader = createCsvReader();
            List<List<String>> records = csvReader.readRecords();
            assertThat(records)
                    .contains(Arrays.asList("jdoe", "10"))
                    .contains(Arrays.asList("kolorobot", "4"))
                    .hasSize(2);
        }
     
        private CsvReader createCsvReader() {
            try {
                Path path = Paths.get("src/test/resources", "sample.csv");
                Reader reader = Files.newBufferedReader(
                    path, Charset.forName("UTF-8"));
                return new CsvReader(reader);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
    }

翻译自: https://www.javacodegeeks.com/2014/05/parsing-a-file-with-stream-api-in-java-8.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值