使用新的Java 8 Streams API解析多行行的CSV文件 [英] Parsing a CSV file for a multiple row rows using new Java 8 Streams API

查看:125
本文介绍了使用新的Java 8 Streams API解析多行行的CSV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问了一个问题一些时间回来解析一个匹配行的CSV文件。在下面显示的示例中,我使用一个bufferingreader读取标题行作为第一步。使用此行,我解析列名称,然后继续搜索匹配的行。我需要搜索匹配行的过滤条件应该基于2列值,而不是下面显示的代码只返回1行 - 可能是因为我使用

I asked a question some time back about parsing CSV files for a single matching row. In the example shown below, I use a bufferedreader to read the header row as the first step. Using this row, I parse the column names and then proceed to search for matching rows. The filter criteria I need to search for the matching row should be based on 2 column values, instead the code shown below only returns the 1 row - presumably because I use

.findFirst().get();

而我需要一些沿着下面几行(但是这个代码是无效的)

Instead I need something along the following lines (but this code is not valid)

List<String> rowCols = reader.lines()
    //.skip(1)
    .map((line) -> Arrays.asList(line.split(",")))
    .filter(list -> 
        !list.get(col1Index).equalsIgnoreCase("0:00") && 
        !list.get(col2Index).equalsIgnoreCase("0:00"))
    .findFirst().get();

,因为这也只是返回1行 - 但是过滤器匹配多行。

as this also just returns 1 row - however the filter matches multiple rows.

我现在需要返回多个匹配的行,但我无法找出正确的语法。

I now need to return multiple matching rows but I cannot figure out the correct syntax.

String fileName = ...
try (BufferedReader reader = new BufferedReader(
    new InputStreamReader(ftpClient.
        retrieveFileStream(fileName)))){
    List<String> columns = reader.lines()
        .findFirst()
        .map(line -> Arrays.asList(line.split(",")))
        .get();
    // find the relevant sections from the CSV file
    // we are only interested in the row with the CA ServiceName
    int serviceNameIndex = columns.indexOf("ServiceName");
    int col1Index = columns.indexOf("Column1");
    int col2Index = columns.indexOf("Column2");
    // we need to know the index positions of the columns
    // also note that due to using a BufferedReader we don't
    // have to re-read the csv file to extract the values
    List<String> rowCols = reader.lines()
        //.skip(1)
        .map((line) -> Arrays.asList(line.split(",")))
        .filter(list -> list.get(serviceNameIndex).equalsIgnoreCase("service1"))
        .findFirst().get();
    EnumMap<Parameter, String> params = new EnumMap(Parameter.class) {{
        put(Parameter.ServiceName, rowCols.get(serviceNameIndex));
        put(Parameter.Column1, rowCols.get(col1Index));
        put(Parameter.Column2, rowCols.get(col2Index));
    }};
    params.put("service1", params);
}


推荐答案

正试图实现完全,但我最好的猜测是,你想返回一个字符串列表,基于分割线像line.split(,)。你的代码不工作,因为在你的过滤器方法后你返回整个字符串列表,但你需要进一步流的列表。换句话说,你需要展平列表以获得如下的内容。

I am not sure what you are trying to achieve exactly but my best guess is that you would like to return a list of strings based on the splitting of the line like line.split(","). Your code doesn't work because after your filter method you return the whole list of strings but you need to further stream the list. In other words you need to flatten the list to get its contents like below

List<String> rowCols = reader.lines()
    .map((line) -> Arrays.asList(line.split(",")))
    .filter(list -> 
        !list.get(col1Index).equalsIgnoreCase("0:00") && 
        !list.get(col2Index).equalsIgnoreCase("0:00"))
    .flatMap(e->e.stream())
    .collect(Collectors.toList());

这应该将每行的内容(已分割的字符串)收集到单个列表中。

This should collect the contents(strings which you've split) of each line into a single list.

这篇关于使用新的Java 8 Streams API解析多行行的CSV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆