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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值