Home > Mobile >  How to get the average duration for each category having films using stream API java
How to get the average duration for each category having films using stream API java

Time:01-07

I have a class Film with the following fields

      String name;
      double duration;
      Collection<String> categories;

My task is to return a Map<String, Double> that represents the average duration by category. I have to use Stream API of Java.

My idea is to form entries of String for the category and List<Double> where the elements are the different durations, and then to use stream api method map and map it to map of string and average. But I am not sure how to do it. Can someone help me how to do it?

CodePudding user response:

You can use the three-argument form of Collectors.groupingBy() with a downstream Collectors.averagingDouble() collector to do it in a single pass. Java 17 example (Including using Map.Entry to emulate a 2-element tuple or pair class):

import java.util.*;
import java.util.stream.*;

public class Demo {
    private record Film(String name, double duration,
                        Collection<String> categories) {}

    public static void main(String[] args) {
        var films = List.of(new Film("The Terminator", 1.783,
                                     List.of("Sci-Fi", "Action")),
                            new Film("Alien", 1.95,
                                     List.of("Sci-Fi", "Horror")));

        Map<String,Double> avgDurations = films.stream()
            // Get a stream of (Category, Duration) pairs
            .flatMap(film ->
                     film.categories().stream()
                     .map(cat -> Map.entry(cat, film.duration())))
            // Group by Category and calculate the average of each
            // group's Durations in a TreeMap
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                                           TreeMap::new,
                                           Collectors.averagingDouble(Map.Entry::getValue)));

        System.out.println(avgDurations);
    }
}

When compiled and run, prints out

{Action=1.783, Horror=1.95, Sci-Fi=1.8664999999999998}
  •  Tags:  
  • Related