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.