Сохранение данных из текстового файла в хэш-карту вместо списка - PullRequest
0 голосов
/ 08 июля 2020

Следующая программа считывает и сохраняет данные из текстового файла вида

1946-01-12;13:00:00;0.3;G
1946-01-12;18:00:00;-2.8;G
1946-01-13;07:00:00;-6.2;G
1946-01-13;13:00:00;-4.7;G
1946-01-13;18:00:00;-4.3;G
1946-01-14;07:00:00;-1.5;G
1946-01-14;13:00:00;-0.2;G

в список массивов. Затем я сохраняю объект погоды в другом классе. Первый метод вычисляет среднюю температуру между двумя датами, вводимыми пользователем, а второй метод вычисляет процентное соотношение «G»: s между двумя датами. хотел бы сохранить данные из файла в хэш-карте вместо списка (для эффективности). Есть ли какие-нибудь простые способы сделать это без необходимости полностью переделывать методы? Я пробовал это:

    public class WeatherDataHandler {
        public void loadData1(String filePath) throws IOException {
        List<String> fileData = Files.readAllLines(Paths.get(filePath));
        Map<LocalDate, List<Weather>> weatherData = new HashMap<LocalDate,List<Weather>>();{
    for(String str : fileData) {
    List<String> parsed = parseData(str);
    LocalDate date = LocalDate.parse(parsed.get(0));
    LocalTime time = LocalTime.parse(parsed.get(1));
    double temperature = Double.parseDouble(parsed.get(2));
    String quality = parsed.get(3);
    Weather weather = new Weather(date,time,temperature,quality);
    
    List<Weather> entries;
    entries = new ArrayList<Weather>();
    if(weatherData.get(date) == null) {
        entries.add(weather);
        weatherData.put(date, entries);
    } else {
        entries = weatherData.get(date);
        entries.add(weather);} 
        }
    }
}
        
        private List<String> parseData(String str) {
            return Arrays.asList(str.split(";"));
        }

Но как мне получить доступ к записям карты в методах?

Ответы [ 2 ]

1 голос
/ 08 июля 2020

Карта ha sh не будет работать для вашего варианта использования. HashMap помогает найти соответствующее значение по ключу. Например, вы можете создать HashMap, который предоставит вам соответствующие данные о погоде для одной даты. Но вы не можете использовать HashMap для ответа на запрос «предоставьте мне все данные о погоде между этими двумя датами» без итерации по диапазону дат. И это то, что вам нужно для ваших методов avarageTemperatures и approvedValues.

Вместо этого вы можете использовать TreeMap. Это потребует изменения вашей программы в нескольких местах.

Объявление переменной:

private List<Weather> weatherData = new ArrayList<>();

Должно стать:

private NavigableMap<LocalDate, List<Weather>> weatherData = new TreeMap<>();

Это "карта из date в список данных о погоде ", потому что для каждой даты существует более одного элемента данных. Если вы можете это изменить, это будет проще.

Далее вместо использования weatherData.add(weather) вам нужно использовать:

weatherData.computeIfAbsent(date, key -> new ArrayList<>()).add(weather);

Опять же, это более сложно, потому что может быть больше чем один элемент на дату.

Наконец, где вы получаете доступ к данным через итерацию:

weatherData.stream().filter(weather -> !weather.getDate().isAfter(dateTo) && !weather.getDate().isBefore(dateFrom))

Вместо этого вы могли бы использовать метод subMap, который напрямую ищет ключевой диапазон:

weatherData.subMap(dateFrom, dateTo).values().stream().flatMap(List::stream)
0 голосов
/ 08 июля 2020

HashMaps работают с парами «ключ-значение». Вы не можете просто сохранить значения во всем текстовом файле без предварительного разделения, а затем итеративно сопоставить их вместе.

...