简体   繁体   English

Java Streams-&gt;从列表中提取特定索引处的值 <List<String> &gt;

[英]Java Streams -> Extract value at a particular index from List<List<String>>

I'm reading a CSV file with Java 8 streams and what is the best way to get the value of a particular column in CSV file For eg. 我正在读取具有Java 8流的CSV文件,例如,获取CSV文件中特定列的值的最佳方法是什么。

firstName,lastName,age,
tom,abraham,18,
liz,abraham,15,
tonny,paul,25

I want to extract the second column, so result set would be abraham;paul How can this be done by Java 8 lambda and Streams? 我想提取第二列,所以结果集将是abraham;paul Java 8 lambda和Streams如何做到这一点?

Welcome to StackOverflow :) 欢迎来到StackOverflow :)

The CSV file could be read as any other text file, no parser is needed and the String::split with File::readAllLines is sufficient: CSV文件可以像其他任何文本文件一样读取,不需要解析器,并且使用File::readAllLines String::splitString::split就足够了:

Set<String> names = Files.readAllLines(Paths.get("file.csv")) // Read all lines of file
                         .stream()                            // Stream them
                         .skip(1)                             // Omit the column names (if any)
                         .map(s -> s.split(";")[1])           // Split by ; and get the 2nd column
                         .collect(Collectors.toSet());        // Collect Strings to Set

I didn't read the label well. 我不太清楚标签。 If you already have parsed List<List<String>> , the simplest way to achieve the very same result is: 如果您已经解析了List<List<String>> ,则获得相同结果的最简单方法是:

Set<String> names = parsedList.stream()
                              .map(row -> row.get(1))       // Get the second column
                              .collect(Collectors.toSet())  // collect to Set<String>

Note the following: 请注意以下几点:

  • There is not needed the distinct() method since collecting to Set assures the distinct elements by definition. 不需要Set distinct()方法,因为收集到Set通过定义确保不同的元素。 If you insist on collecting to List<String> , replace the last line with: 如果您坚持收集到List<String> ,则将最后一行替换为:

      .... .distinct() .collect(Collectors.toList()); 

    This way is valid for both of my suggested solutions. 这种方式对我建议的两种解决方案均有效。

  • An exception might appear at the following lines in case of irregular CSV pattern or escaped ; 如果CSV模式不规则或逃脱了,则以下行可能出现异常; characters: 特点:

    • map(s -> s.split(";")[1])
    • map(list -> list.get(1))

    Then you need to use a parser. 然后,您需要使用解析器。

Files.readAllLines(Paths.get("my.csv")).stream()
        .skip(1)
        .map(s -> s.split(";")[1])
        .distinct()
        .collect(Collectors.toList()).forEach(System.out::println);

Is the simplest way, but I would prefer to use regular expression and the Matcher for this case. 是最简单的方法,但在这种情况下,我更喜欢使用正则表达式和Matcher。

You can use a map stream. 您可以使用地图流。

Files.lines(Paths.get("file path")).map(row -> row.split(";")).map(row -> row[1]).distinct().collect(Collectors.toList());

//first map: transform string to Array.
//Second map: choose first index array.
//distinct: remove duplicates elements.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM