将数据从文本文件存储到散列图而不是列表
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
到数组列表。然后我将天气对象存储在另一个 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;
}
}
现在,我不想将映射实现到方法,而是想将文件中的数据存储到散列映射而不是列表(为了提高效率)。有没有简单的方法可以做到这一点而不必完全重做这些方法?我试过这个:
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(";"));
}
但是如何在方法中访问地图的条目?
HashMaps 适用于键值对。如果不首先拆分然后迭代地将它们映射在一起,您不可能简单地将值存储在整个文本文件中。
哈希映射不适用于您的用例。 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)
以下程序从格式为
的文本文件中读取和存储数据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
到数组列表。然后我将天气对象存储在另一个 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;
}
}
现在,我不想将映射实现到方法,而是想将文件中的数据存储到散列映射而不是列表(为了提高效率)。有没有简单的方法可以做到这一点而不必完全重做这些方法?我试过这个:
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(";"));
}
但是如何在方法中访问地图的条目?
HashMaps 适用于键值对。如果不首先拆分然后迭代地将它们映射在一起,您不可能简单地将值存储在整个文本文件中。
哈希映射不适用于您的用例。 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)