Java: Как суммировать все значения одного столбца на основе критериев во втором столбце, используя HashMaps - PullRequest
0 голосов
/ 15 марта 2020

У меня есть CSV-файл, который содержит примерно 500 000 строк и 22 столбца полетных данных. 5-я колонка содержит номер хвоста каждого самолета для каждого полета. 22-й столбец содержит пройденное расстояние для каждого полета. Я пытаюсь суммировать общее пройденное расстояние (столбец 22) для каждого номера хвоста (столбец 5).

Я создал HashMap, содержащий все данные с именем map1. Я создал 2-й HashMap с именем planeMileages для размещения каждого номера рейса и общего пройденного расстояния. Я использую вложенный оператор if go через каждую строку map1 и проверяю, содержится ли уже номер хвоста в planeMileages. Если это в planeMileages, то я хочу добавить к accumulatedMileages для этого ключа. Если он не содержится, я хотел бы ввести ключ вместе с его первым значением расстояния.

Мне кажется, что текущий код, который я написал, звучит правильно, но он дает неправильный результат, выводя неверный номер хвоста. Можете ли вы взглянуть и сообщить мне, что я пропускаю в моем основном методе? Спасибо!

public class FlightData {

    HashMap<String,String[]>  dataMap;

        public static void main(String[] args) {

            FlightData map1 = new FlightData();
            map1.dataMap = map1.createHashMap();

            HashMap<String, Integer> planeMileages = new HashMap();
            //Filling the Array with all tail numbers
            for (String[] value : map1.dataMap.values()) {

                if(planeMileages.containsKey(value[4])) {  
                    int accumulatedMileage = planeMileages.get(value[4]) + Integer.parseInt(value[21]);
                    planeMileages.remove(value[4]);
                    planeMileages.put(value[4], accumulatedMileage);
                } 
                else {
                    planeMileages.put(value[4],Integer.parseInt(value[21]));
                }
            }


            String maxKey = Collections.max(planeMileages.entrySet(), Map.Entry.comparingByValue()).getKey();

            System.out.println(maxKey);


        }





       public HashMap<String,String[]> createHashMap() {
            File flightFile = new File("flights.csv");
            HashMap<String,String[]> flightsMap = new HashMap<String,String[]>();

            try {
            Scanner s = new Scanner(flightFile);
            while (s.hasNextLine()) {

                    String info = s.nextLine();
                    String [] piecesOfInfo = info.split(",");

                        String flightKey = piecesOfInfo[4] + "_" + piecesOfInfo[2] + "_" + piecesOfInfo[11]; //Setting the Key
                        String[] values = Arrays.copyOfRange(piecesOfInfo, 0, piecesOfInfo.length);

                        flightsMap.put(flightKey, values);


            }
            s.close();
            }


           catch (FileNotFoundException e)
           {
             System.out.println("Cannot open: " + flightFile);
           }

            return flightsMap;
        }
}

Пожалуйста, посмотрите несколько строк моего CSV-файла ниже:

Flights.csv

DayofMonth  DayOfWeek   FlightDate  UniqueCarrier   TailNum OriginAirportID Origin  OriginStateName DestAirportID   Dest    DestStateName   DepTime DepDelay    WheelsOff   WheelsOn    ArrTime ArrDelay    Cancelled   CancellationCode    Diverted    AirTime Distance
3   1   10/3/2016   AA  N786AA  10721   BOS Massachusetts   12478   JFK New York    556 -4  623 703 709 -6  0       0   40  187
4   2   10/4/2016   AA  N794AA  10721   BOS Massachusetts   12478   JFK New York    554 -6  615 703 712 -3  0       0   48  187
1   6   10/1/2016   AA  N783AA  12478   JFK New York    12892   LAX California  823 -7  844 1104    1111    -30 0       0   320 2475
2   7   10/2/2016   AA  N798AA  12478   JFK New York    12892   LAX California  847 17  904 1131    1159    18  0       0   327 2475
3   1   10/3/2016   AA  N786AA  12478   JFK New York    12892   LAX California  825 -5  838 1109    1131    -10 0       0   331 2475
4   2   10/4/2016   AA  N794AA  12478   JFK New York    12892   LAX California  826 -4  848 1114    1132    -9  0       0   326 2475

Ответы [ 3 ]

3 голосов
/ 15 марта 2020

Вот немного более OOP способ сделать это.

Вы расширяете HashMap и добавляете два новых метода, один для добавления рейсов, а другой для расчета общего расстояния. Таким образом, вы не будете постоянно удалять и добавлять обратно измененные значения в HashMap. Вы можете расширить это в соответствии с вашими потребностями.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        FlightData flightData = getFlightDataFromFile();
        flightData.getDistanceTraveled("tail number");
    }

    public static FlightData getFlightDataFromFile() {
        File flightFile = new File("flights.csv");
        FlightData flightData= new FlightData();

        try {
            Scanner s = new Scanner(flightFile);
            while (s.hasNextLine()) {
                String info = s.nextLine();
                String[] piecesOfInfo = info.split(",");
                String tailNr= piecesOfInfo[4];
                Flight flight = new Flight(piecesOfInfo[6], piecesOfInfo[9], Integer.parseInt(piecesOfInfo[21]));
                flightData.addFlight(tailNr, flight);
            }
            s.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cannot open: " + flightFile);
        }
        return flightData;
    }
}

class FlightData extends HashMap<String,List<Flight>> {

    void addFlight(String tailNr, Flight flight) {
        computeIfAbsent(tailNr, flights -> new ArrayList<>()).add(flight);
    }

    int getDistanceTraveled(String tailNr) {
        int distance = 0;
        for (Flight f : get(tailNr)) distance+= f.distance;
        return distance;
    }

}

class Flight {
    String from;
    String to;
    int distance;

    public Flight(String from, String to, int distance) {
        this.from = from;
        this.to = to;
        this.distance = distance;
    }
}
1 голос
/ 15 марта 2020

Попробуйте, и если мили очень велики, измените Integer на Long, а затем отметьте

   HashMap<String, Integer> planeMileages = new HashMap<>();

    for (String [] value : flightsMap.values()) {

        if(planeMileages.containsKey(value[4])) {

            planeMileages.put(value[4], planeMileages.get(value[4])+Integer.valueOf(value[21]));

        } else {
            planeMileages.put(value[4], Integer.valueOf(value[21]));
        }
    }
1 голос
/ 15 марта 2020

Здравствуйте, вы можете проверить это?

public static void main(String[] args) throws  IOException {

    Map<String, String[]> map = createMap();
    Map<String, Long> planeMileages = map
            .entrySet()
            .stream()
            .collect(Collectors.groupingBy(o -> o.getValue()[4],
                    Collectors.collectingAndThen(
                            Collectors.summarizingInt(value ->
                                    Integer.parseInt(value.getValue()[21])), IntSummaryStatistics::getSum
                    )
            ));
    String maxKey = planeMileages.entrySet().stream().max(Comparator.comparing(Map.Entry::getValue)).get().getKey();
    System.out.println("max key: "+ maxKey);
}

public static Map<String, String[]> createMap() throws IOException {
    try (BufferedReader a = Files.newBufferedReader(Paths.get("flights.csv"))) {
        return a.lines().map(s -> s.split(","))
                .collect(Collectors.toMap(piecesOfInfo -> String.join("_", piecesOfInfo[4], piecesOfInfo[2], piecesOfInfo[11]), Function.identity()));
    }
}

public static Map<String, String[]> createMapLastDupWins() throws IOException {
    try (BufferedReader a = Files.newBufferedReader(Paths.get("flights.csv"))) {
        return a.lines().map(s -> s.split(","))
                .collect(Collectors.toMap(piecesOfInfo -> String.join("_", piecesOfInfo[4], piecesOfInfo[2], piecesOfInfo[11]), Function.identity(), (strings, strings2) -> {
                    //if this helps than data is duplicated
                    return strings2;
                }));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...