Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 lambdas to find averages of list of maps

How, with Java-8 streams/lambdas, can I find averages of List of maps by keys?

Example:

List<Map<String, Double>> users = Arrays.asList(
  new HashMap<String, Double>()
    {{
      put("weight", 109.0);
      put("height", 180.2);          
     }},
  new HashMap<String, Double>()
    {{
      put("weight", 59.0);
      put("height", 186.2);          
     }}
 );

 Map<String, Double> statistics = 
 //<MISSED CODE with lambdas> (?)

 System.out.println(statistics);
 //{weight=84.0, height=183.1)

With old good foreachs it's quite simple, I am wondering if that could be achieved with lambdas. The reason I need it is that I am going to use Apache Spark and Java-8 lambdas will be a more standard approach for it.

like image 719
Bogdan Avatar asked Jul 13 '16 08:07

Bogdan


People also ask

How do you find the average of a list in Java 8?

The logic is very simple. First, we will initialize a variable sum to 0 that holds the sum of the list elements. Declare another element say average (avg), it holds the average of the list. We have created an instance of the ArrayList class and invoked the add() method to add the elements to the List.

How do you find the average of numbers using stream API in Java?

IntStream average() method in Java The average() method of the IntStream class in Java returns an OptionalDouble describing the arithmetic mean of elements of this stream, or an empty optional if this stream is empty. It gets the average of the elements of the stream.

What is .MAP in Java 8?

Java 8 Stream's map method is intermediate operation and consumes single element forom input Stream and produces single element to output Stream. It simply used to convert Stream of one type to another.


1 Answers

As Andrew Tobilko said, you should use a proper data structure not Maps.

If you insist on using List<Map<>> then you need to Stream::flatMap the Map::entrySet and use the proper Collectors.


List<Map<String, Double>> users = Arrays.asList(new HashMap<String, Double>() {
  {
    put("weight", 109.0);
    put("height", 180.2);
  }
}, new HashMap<String, Double>() {
  {
    put("weight", 59.0);
    put("height", 186.2);
  }
});

Map<String, Double> statistics = users.stream().flatMap(m -> m.entrySet().stream())
    .collect(
        Collectors.groupingBy(Entry::getKey, Collectors.averagingDouble(Entry::getValue))
    );

System.out.println(statistics);
// {weight=84.0, height=183.2}
like image 192
Flown Avatar answered Oct 15 '22 21:10

Flown