0

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
  • If you create a class containing 2 strings, you can replace `.map(list -> list.get(titleIndex))` with something which creates an instance of that class, i.e. `.map(list -> new MyClass(list.get(titleIndex), list.get(otherIndex)))`. The downstream methods would, of course, also have to change to support the object instead of a string – ODDminus1 Aug 18 '23 at 05:02

1 Answers1

2

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)))
    
hermit
  • 1,048
  • 1
  • 6
  • 16