Search code examples
javacsvopencsvcsv-parser

How to read a CSV file, filter by a particular record and store it in different java object based on the records


I have a CSV file like below

Rahul|S|74|72|71
Randy|T|20000|2
Abinav|T|30000|3
Amrit|S|82|81|80

The above csv has information about both student's and teacher's of a school. With the help of 2nd column we will be able to identify if the information is related to a student or a teacher

|S| - Student
|T| - Teacher

Now i want to filter the CSV file based on the second record and store student related information in a Student class and teacher related information in Teacher class

I have tried to do the same by using opencsv like below

public class Student {
  @CsvBindByPosition(position = 0)
  private String name;

  @CsvBindByPosition(position = 1)
  private String mathsScore;

  @CsvBindByPosition(position = 2)
  private String scienceScore;

  @CsvBindByPosition(position = 3)
  private String englishScore;
}

public class Teacher {
  @CsvBindByPosition(position = 0)
  private String name;

  @CsvBindByPosition(position = 1)
  private String salary;

  @CsvBindByPosition(position = 2)
  private String yearOfExp;
}

And my parsing code would look like below

List<Student> studentsList = new CSVToBeanBuilder(new FileReader(csvFile))
      .withType(Student.class)
      .build().parse();

This works fine if the csv has only one type of record (either Student or Teacher). Is it possible to filter csv based on record type and parse it to different java objects accordingly.

I know we can achieve it if we loop through the csv and read line by line but i don't want to do that since our csv file will be too large and doing so would affect the performance.


Solution

  • As I can see you need to code like that:

    List<Student> parse = new CsvToBeanBuilder<Student>(new FileReader("C:\\test\\test.csv"))
                    .withType(Student.class)
                    .withSeparator('|')
                    .withFilter(line -> line[1].equals("S"))
                    .build().parse();
    

    I do not see the way to set different types mapping within one builder.

    Also be ware that '@CsvBindByPosition(position = 1)' leads to second column. It always 'S' for Student.class.