Calculating Average from a CSV File

后端 未结 4 1569
感动是毒
感动是毒 2021-01-21 23:35

I have a CSV file, format as follows:

City,Job,Salary Delhi,Doctors,500 Delhi,Lawyers,400 Delhi,Plumbers,100 London,Doctors,800 London,Lawyers,700 London,Plumbers,

相关标签:
4条回答
  • 2021-01-22 00:06

    The first line contains the word "Salary" in the third spot. Put br.readLine()before the loop and everything should be fine.

    You have:

    br = new BufferedReader(new FileReader(csv));
    try {
      while ((line = br.readLine()) != null) {
    

    Change it to:

    br = new BufferedReader(new FileReader(csv));
    br.readLine()
    try {
      while ((line = br.readLine()) != null) {
    
    0 讨论(0)
  • 2021-01-22 00:13

    First, use a CSV parser - I will use OpenCSV in this example. I have no affiliation with OpenCSV, it's just what I have in my POM at the moment.

    First, create a class:

    public class Salary {
        private String city;
        private String job;
        private long salary;
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getJob() {
            return job;
        }
    
        public void setJob(String job) {
            this.job = job;
        }
    
        public long getSalary() {
            return salary;
        }
    
        public void setSalary(long salary) {
            this.salary = salary;
        }
    }
    

    Now your CSV has three columns, and the header of the CSV matches the property names of our bean, so we can simply use a HeaderColumnNameMappingStrategy to determine which properties to set on the bean:

    final HeaderColumnNameMappingStrategy<Salary> mappingStrategy = new HeaderColumnNameMappingStrategy<>();
    mappingStrategy.setType(Salary.class);
    

    Now we just need to parse the CSV file into a List of our beans:

    final CsvToBean<Salary> csvToBean = new CsvToBean<>();
    try (final Reader reader = ...) {
        final List<Salary> salaries = csvToBean.parse(mappingStrategy, reader);
    }
    

    Okay.

    Now, how do you get an average salary from this mess? Just use a Java 8 Stream on the result:

        final LongSummaryStatistics statistics = salaries.stream()
                .mapToLong(Salary::getSalary)
                .summaryStatistics();
    

    Now we can get all sorts of useful information:

    final long min = statistics.getMin();
    final double average = statistics.getAverage();
    final long max = statistics.getMax();
    
    0 讨论(0)
  • 2021-01-22 00:25

    br.readLine() before the while-loop will avoid header line problem, but if your data is not correct you will get same Exception again, so, in order to make a safer method you can change this line:

    int sal=Integer.parseInt(country[2]);
    

    With a try-catch block to iterate through entire file even if a value is not a valid number

    int sal;
    try {
        sal=Integer.parseInt(country[2]);
    } catch (NumberFormatException e) {
        // if you want here you can show an error message 
        // to give feedback to the user there is not a valid number
    }
    
    0 讨论(0)
  • 2021-01-22 00:28

    Skip the first line of the CSV file. Do an additional

    br.readLine()
    

    before the while.

    You might also want to add some format checks to be sure the file you are reading is in the correct format.

    0 讨论(0)
提交回复
热议问题