简体   繁体   中英

How do I read multiple CSV files to sort data in Java?

So, my Java project has two CSV files that needs to read and print some sort the data from high to low.

First CSV file has date, location, new_cases, new_deaths, total_cases, total_deaths format.

Second CSV file has Country, location, continent, population_year, population format.

What I'm trying to do is to read both data, run a function to calculate continent data, and come up with continent(string), total_cases(int) and sort it according to high to low. then print the whole thing

Example output:

Continent (continent, csv2): ------ Total Cases:(total_cases,csv1)

Oceania 123456

Australia 12345

Europe 123

The code I wrote so far included below, please help me with deriving and sorting the data.

import java.io.FileReader;
import java.io.*;
import java.util.Scanner;
import java.util.* ;
public class Main {

    static void loadData() {

        String pathFile1 = "./locations.csv";
        String pathFile2 = "./full_data.csv";
        String row;
        try {

            BufferedReader csvReader = new BufferedReader(new FileReader(pathFile1));

            while ((row = csvReader.readLine()) != null) {
              System.out.println(row);
            }
            csvReader.close();


            csvReader = new BufferedReader(new FileReader(pathFile2));

            while ((row = csvReader.readLine()) != null) {
                System.out.println(row);

            }
            csvReader.close();


        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    private static void add() {
    }

    public static void main(String[] args) {


        Scanner scnr = new Scanner(System.in);
        int choice = -1;
        System.out.println("*************************************************************");
        System.out.println("**** COVID 19 Global Statistics *****************************");
        System.out.println("*************************************************************");
        do {
            System.out.println("[1] Load Data From Files");
            System.out.println("[2] Print Continents Total Cases (Lowest to Highest)");
            System.out.println("[3] Print Continents Total Cases (Highest to Lowest)");
            System.out.println("[4] Print Continents Total Deaths (Lowest to Highest)");
            System.out.println("[5] Print Continents Total Deaths (Highest to Lowest)");
            System.out.println("[6] Prioritize top countries for testing based on new cases per 1 million");
            System.out.println("[7] To Exit");
            System.out.println("Please enter your choice:");
            choice = scnr.nextInt();
            Map<String, Integer> hm1;
            switch (choice) {
                case 1:
                    System.out.println("Loading files ...");
                    loadData();
                    System.out.println("Files loaded successfully!");
                    break;
                case 2:
                    break;
                case 3:

                    break;
                case 4:
                    break;
                case 5:

                var requestedNum = scnr.nextInt();
                System.out.println("Continent:        Total Cases:");

                    break;
                case 6:
                System.out.println("How many countries to pull from the priorities list:");
                    break;
                case 7:
                    System.out.println("Thank you for using our system..Goodbye!");
                    break;
                default:
                    System.out.println("Please a choice 1 - 7");
                    break;
            }
        } while (choice != 7);
    }
}

The continent at position 3 and total at position 5, read the first file and get the total cases and I guess every row in the first file related to the same row in the second file.

Then create a map with continent and number related to that continent and sort based on the total cases

 public static Map<String, Long> loadData() {
        String pathFile1 = "./locations.csv";
        String pathFile2 = "./full_data.csv";
        String row;
        try {

            BufferedReader csvReader = new BufferedReader(new FileReader(pathFile1));
            List<Long> totalCases = new ArrayList<>();
            while ((row = csvReader.readLine()) != null) {
                String[] split = row.split(",");
                totalCases.add(Long.parseLong(split[4])); // total at position 5
            }
            csvReader.close();

            csvReader = new BufferedReader(new FileReader(pathFile2));
            Map<String, Long> map = new LinkedHashMap<>();
            int i = 0;
            while ((row = csvReader.readLine()) != null) {
                String[] split = row.split(",");
                String continent = split[2]; // continent at position 3
                map.put(continent, map.getOrDefault(continent, 0L) + totalCases.get(i));
                i++;
            }
            csvReader.close();

            return map.entrySet().stream().sorted(Entry.<String, Long>comparingByValue().reversed())
                    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue(), (e1, e2) -> e2, LinkedHashMap::new));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

I will give the headlines of how I would do it:

  1. I would create a class from the csv1 format data, and another for csv2 format data. Class derived from csv1 would look like
Class CasesStatisticData{
    Date date;
    String location;
    long new_cases;
    long new_deaths;
    long total_cases;
    long total_deaths;
}

and from csv2

Class CountryData{
    String name
    String location
    String continent
    long population_year
    long population
}
  1. I would create one ArrayList for each class
  2. For each csv, for each line, I would create a new Object of the class associated to that csv and put that object on the list associated with that csv
  3. I would create a TreeMap for each relation that I want. For example: you want each continent to be mapped on a list of countries. I would create TreeMap<String, List<CountryData>> countriesByContinents
  4. I would iterate on that TreeMap keys, for each key, would count the total data on the list it is mapped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM