I am trying to convert the following Java code to Java 8. I have written the following code to calculate the average temperatures.
public static double calculateTemps(String country, Map<String, List<Temperatures>> tempMap) {
double temp = 0.0f;
int count = 0;
if (country.equalsIgnoreCase("India")) {
for (Map.Entry<String, List<Temperatures>> m : tempMap.entrySet()) {
for (Temperatures t : m.getValue()) {
temp = temp + t.getTemp();
count++;
}
}
}
System.out.println(count);
return temp / count;
}
The above code is working fine. Now, I am trying to convert it to Java 8. I have written the following code, but I am getting compile-time errors
public static double calculateTemps(String country, Map<String, List<Temperatures>> tempMap) {
double temp = 0.0f;
int count = 0;
tempMap.entrySet().stream().filter(temps -> temps.getKey()
.equalsIgnoreCase("India"))
.forEach(temps -> {
temp = temp + temps.getValue();
}).collect(Collectors.toSet());
}
I thought map is better suited here, but after going through a few questions on Stack Overflow I thought for-each is better suited here. Not sure. Could anyone please enlighten me?
Advertisement
Answer
Your code has multiple problems:
- You’re trying to add
Temperatures
objects totemp
instead ofTemperatures.getTemp()
- You’re trying to modify variable
temp
inside a lambda, buttemp
must be effectively final - You’re calling
collect
on the void methodforEach
, which is not possible.
You can make use of features of DoubleStream
to calculate the average:
return tempMap.entrySet().stream()
.filter(temps -> temps.getKey().equalsIgnoreCase("India"))
.flatMap(temps -> temps.getValue().stream())
.mapToDouble(temp -> temp.getTemp())
.average().orElse(0.0);
As an aside, the filter
condition is different from the condition used in the original method (which checked against the country
parameter), but I have preserved it from your original attempt. Check carefully if it is really what you need.