2

I have CSV file which is in the form as below

student, year, subject, score1, score2, score3
Alex, 2010, Math, 23, 56, 43
Alex, 2011, Science, 45, 32, 45
Matt, 2009, Art, 34, 56, 75
Matt, 2010, Math, 43, 54, 54

I'm trying to find an optimal solution to read the CSV file and load it to a map for lookup purposes i.e. Map<String, Map<String, List<SubjectScore>>>. The first string key is for student, the next string key is for year.

class SubjectScore {
  private String subject;
  private int score1;
  private int score2;
  private int score3;
}

If there is a better way to store the CSV structure to get SubjectScore based on student and year information, I'll like to know that.

1
  • 1
    I‘d recommend to use a dependency like open CSV and then iterate trough the rows and map them. In the best case you write a method ‘transformToMap‘ which takes an Array of Strings (the row) as parameter and outputs your result. Commented Jun 13, 2020 at 7:44

1 Answer 1

3

You can add some constructors to SubjectStore and use streams to read the file contents and convert it to your required data structure:

public class SubjectScore {
    private final String subject;
    private final int score1;
    private final int score2;
    private final int score3;

    SubjectScore(String subject, int s1, int s2, int s3) {
        this.subject = subject;
        this.score1 = s1;
        this.score2 = s2;
        this.score3 = s3;
    }

    SubjectScore(String subject, String s1, String s2, String s3) {
        this(subject, Integer.parseInt(s1), Integer.parseInt(s2), Integer.parseInt(s3));
    }
    // getters/toString
}

Map<String, Map<String, List<SubjectScore>>> res = Files.lines(Path.of("data.csv"))
            .skip(1) // skip header line
            .map(line -> line.split("\\s*,\\s*")) // get columns
            .collect(
                Collectors.groupingBy(arr -> arr[0], TreeMap::new, // key: student
                Collectors.groupingBy(arr -> arr[1], TreeMap::new, // key: year
                Collectors.mapping(arr -> new SubjectScore(arr[2], arr[3], arr[4], arr[5]), Collectors.toList())
            )));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.