[英]Storing data from text file to hashmap instead of list
以下程序從表單的文本文件中讀取和存儲數據
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
到數組列表。 然后我將天氣 object 存儲在另一個 class 中。 第一種方法計算用戶輸入的兩個日期之間的平均溫度,第二種方法計算兩個日期之間“G”:s 的百分比。
/**
* Provides methods to retrieve temperature data from a weather station file.
*/
public class WeatherDataHandler {
private List<Weather> weatherData = new ArrayList<>();
public void loadData(String filePath) throws IOException {
List<String> fileData = Files.readAllLines(Paths.get("filepath"));
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);
weatherData.add(weather);
}
}
private List<String> parseData(String s) {
return Arrays.asList(s.split(";"));
}
/**
* Search for average temperature for all dates between the two dates (inclusive).
* Result is sorted by date.
*/
public Map<LocalDate, Double> avarageTemperatures(LocalDate dateFrom, LocalDate dateTo) {
Map<LocalDate, Double> Averagetemperature = weatherData.stream().filter(weather -> !weather.getDate().isAfter(dateTo) && !weather.getDate().isBefore(dateFrom))
.collect(Collectors.groupingBy(Weather::getDate,
Collectors.averagingDouble(Weather::getTemperature)));
return Averagetemperature;}
/**
* Search for percentage of approved values between the two dates (inclusive).
*/
public Double approvedValues(LocalDate dateFrom, LocalDate dateTo) {
double percentageApproved = weatherData.stream().filter(weather -> !weather.getDate().isAfter(dateTo) && !weather.getDate().isBefore(dateFrom))
.mapToInt(obj -> obj.getQuality().equals("G") ? 1 : 0)
.summaryStatistics()
.getAverage();
return percentageApproved;
}
}
現在,我不想將映射到方法,而是將文件中的數據存儲到 hashmap 而不是列表(為了提高效率)。 有沒有簡單的方法可以做到這一點而不必完全重做這些方法? 我試過這個:
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(";"));
}
但是如何在方法中訪問 map 的條目?
hash map 不適用於您的用例。 HashMap 幫助您找到匹配的值,給定一個鍵。 例如,您可以制作一個 HashMap,它為您提供給定日期的匹配天氣數據。 但是,您不能使用 HashMap 來回答查詢“給我這兩個日期之間的所有天氣數據”而不迭代日期范圍。 這就是您的avarageTemperatures
和approvedValues
方法所需要的。
您可以使用的是TreeMap
。 這將需要在幾個地方更改您的程序。
變量聲明:
private List<Weather> weatherData = new ArrayList<>();
必須變成:
private NavigableMap<LocalDate, List<Weather>> weatherData = new TreeMap<>();
這是一張“從日期到天氣數據列表的地圖”,因為每個日期有多個數據項。 如果你能改變它,它會更簡單。
接下來,您需要使用以下命令,而不是使用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)
HashMaps 適用於鍵值對。 您不可能在不先拆分然后迭代地將它們映射在一起的情況下簡單地將值存儲在整個文本文件中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.