Search code examples
javalambdacsvreader

Read two columns by header from csv file using java 8


I want to read two columns (col5 and col7) from csv file by header.

With below code I can read only one column header (col5). Is there any way to read two columns in the same map itself.

Why I choose map is I need to process data later.

public static List<String> getData() throws IOException {
        String titleToSearchFor = "col5";
        Path path = Paths.get("D:/blackduck_sample.txt");

        if (Files.exists(path)) {
            List<String> lines = Files.readAllLines(path);

            List<String> columns = Arrays.asList(lines.get(0).split(","));

            int titleIndex = columns.indexOf(titleToSearchFor);

            List<String> values = lines.stream().skip(1).map(line -> Arrays.asList(line.split(",")))
                    .map(list -> list.get(titleIndex)).filter(Objects::nonNull).filter(s -> s.trim().length() > 0)
                    .collect(Collectors.toList());

            return values;
        }

        return new ArrayList<>();

    }

My sample CSV file

col1,col2,col3,col4,col5,col6,col7,col8
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:SnakeYAML:2.1:3,TRUE,FALSE,OverDue
CVM Finding,12345,sdc,CAP,12345:sdc-event-generation-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,Overdue
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:Apache Tomcat:9.0.70:1,TRUE,FALSE,Due in <= 90
CVM Finding,12345,sdc,CAP,12345:sdc-bh-registry-svc:Jettison - Json Stax implementation:1.5.3:1,TRUE,FALSE,Due in <=90
CVM Finding,12345,sdc,CAP,12345:sdc-event-generation-svc:Apache Tomcat:9.0.70:2,TRUE,FALSE,Due in >90
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:jackson-databind:2.14:1,TRUE,FALSE,OverDue
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:jackson-databind:2.14:1,TRUE,FALSE,Due in <= 90
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,Overdue
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,OverDue

I tried to search google and stackfoverflow and ended up with either one column or read by index

String[] cols = line.split(cvsSplitBy);
    System.out.println("Coulmn 5= " + cols[5] + " , Column 7=" + cols[7]);

The output should be

12345:sdc-posistion-svc:SnakeYAML:2.1:3,OverDue
12345:sdc-event-generation-svc:SpringBoot:2.1.2.Release:1,Overdue
12345:sdc-event-subscription-svc:Apache Tomcat:9.0.70:1,Due in <= 90
12345:sdc-bh-registry-svc:Jettison - Json Stax implementation:1.5.3:1,Due in <=90
12345:sdc-event-generation-svc:Apache Tomcat:9.0.70:2,Due in >90
12345:sdc-posistion-svc:jackson-databind:2.14:1,OverDue
12345:sdc-event-subscription-svc:jackson-databind:2.14:1,Due in <= 90
12345:sdc-event-subscription-svc:SpringBoot:2.1.2.Release:1,Overdue
12345:sdc-posistion-svc:SpringBoot:2.1.2.Release:1,OverDue

Solution

  • According to the csv shared by you, it is acually col8 and not col7.

    Most of the work you have already done. Like you have fetched col5, you can fetch col8 as well.

    1. As you have done for col5, define variable to hold col8 as well:

      String titleForCol8 = "col8";
      
    2. Find the index for col8:

      int col8Idex = columns.indexOf(titleForCol8);
      
    3. Append col5 and col8 in the result in the stream processing segment.

      .map(list -> list.get(titleIndex).concat(",").concat(list.get(col8Idex)))