I have a temperature record something like this
dt |AverageTemperature |AverageTemperatureUncertainty|City |Country |Latitude|Longitude
----------+-------------------+-----------------------------+-------+--------+--------+---------
1963-01-01|-5.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1963-02-01|-4.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
1964-01-01|-5.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1964-02-01|-4.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
1965-01-01|11.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1965-02-01|12.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
I have to parse this into a POJO and calculate the average delta as per the following problem statement:
Use the Streams API to calculate the average annual temperature delta for each country. To calculate delta the average temperature in 1900 would be subtracted from the average temperature in 1901 to obtain the delta from 1900 to 1901 for a particular city. The average of all these deltas is the average annual temperature delta for a city. The average of all cities in a country is the average of a country.
My Temperate POJO looks like following having getters and setters
public class Temperature {
private java.util.Date date;
private double averageTemperature;
private double averageTemperatureUncertainty;
private String city;
private String country;
private String latitude;
private String longitude;
}
I have maintained a list of temperatures as this problem is to be achieved using streams.
To calculate the delta I am trying to use the following streams but I am still unable to calculate the actual delta, as I have to calculate the average country delta, I have performed grouping over country, city and date.
Map<String, Map<String, Map<Integer, Double>>> countriesMap = this.getTemperatures().stream()
.sorted(Comparator.comparing(Temperature::getDate))
.collect(Collectors.groupingBy(Temperature::getCountry,
Collectors.groupingBy(Temperature::getCity,
Collectors.groupingBy
(t -> {
Calendar calendar = Calendar.getInstance();
calendar.setTime(t.getDate());
return calendar.get(Calendar.YEAR);
},
Collectors.averagingDouble(Temperature::getAverageTemperature)))));
In order to calculate the delta we will have to calculate the differences
for the Map<Integer, Double>.
For calculating the difference I came up with the following code but couldn't connect following code with the above one
Stream.of(10d, 20d, 10d) //this is sample data that I that I get in `Map<Integer, Double>` of countriesMap
.map(new Function<Double, Optional<Double>>() {
Optional<Double> previousValue = Optional.empty();
@Override
public Optional<Double> apply(Double current) {
Optional<Double> value = previousValue.map(previous -> current - previous);
previousValue = Optional.of(current);
return value;
}
})
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println);
How can I calculate the delta using streams in one go or how to perform stream operations over countriesMap in order to calculate delta and acheive the mentioned problem statment.?