Functional Programming - Group by

Imperative Vs Functional

About

grouping by is a function that group elements with the same attribute in a apart collection.

The output of a group by operations is normally a map where:

  • the key is the elements to group by
  • and the value is the elements grouped in a collection

It's a final collect operation that is followed (cascaded) generally with a reduce operation.

Syntax

Map<Classifier, Collection> result = groupingBy(classifier, toCollection());

Example

Only collect Operation

  • Grouping by gender (Ref)
Map<Person.Sex, List<Person>> byGender =
    roster
        .stream()
        .collect(
            Collectors.groupingBy(Person::getGender));
  • retrieves the names of each member in the collection roster and groups them by gender (Ref)
Map<Person.Sex, List<String>> namesByGender =
    roster
        .stream()
        .collect(
            Collectors.groupingBy(
                Person::getGender,                      
                Collectors.mapping(
                    Person::getName,
                    Collectors.toList())));
  • to compute the set of last names of people in each city, where the city names are sorted (ref
Map<City, Set<String>> namesByCity = people
    .stream()
    .collect(groupingBy(
        Person::getCity, 
        TreeMap::new, // The constructor
        mapping(Person::getLastName, toSet())
        ));

With reduce operation

  • Retrieves the total age of members of each gender
Map<Person.Sex, Integer> totalAgeByGender =
    roster
        .stream()
        .collect(
            Collectors.groupingBy(
                Person::getGender,                      
                Collectors.reducing(
                    0,
                    Person::getAge,
                    Integer::sum)));
  • retrieves the average age of members of each gender (Ref)
Map<Person.Sex, Double> averageAgeByGender = roster
    .stream()
    .collect(
        Collectors.groupingBy(
            Person::getGender,                      
            Collectors.averagingInt(Person::getAge)));
Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
Map<City, Person> tallestByCity = people
    .stream()
    .collect( groupingBy( Person::getCity, reducing(BinaryOperator.maxBy(byHeight) ) ));
  • to calculate the longest last name of residents in each city:
Comparator<String> byLength = Comparator.comparing(String::length);
Map<City, String> longestLastNameByCity = people
    .stream()
    .collect( groupingBy(
        Person::getCity,
        reducing(Person::getLastName, BinaryOperator.maxBy(byLength))
        )
    );





Discover More
Imperative Vs Functional
Functional Programming - Reduce - Reduction Operation (fold)

A (reduction|reduce) operation (also called a fold) is a functional programming function. Reduction operations are terminal operations. They takes a sequence of input elements and returns: a single...
Data System Architecture
Logical Data Modeling - Classifier (Label, Class, Tag) - Descriptif Attribute

A label is an attribute that describes its entity or relationship with nominal data. A label is also known as: a tag a class or just a nominal attribute a classifier a group a category Classifiers...



Share this page:
Follow us:
Task Runner