Tuesday, 18 March 2025

Overview of Groupingby in Java8 streams

 Overview of groupingBy in Java 8 Streams

The groupingBy collector in Java 8 is part of the Collectors class and is used to group elements in a stream by a specified classifier function. It works similarly to the SQL GROUP BY statement, where data is categorized based on certain attributes. The result is typically a Map, where the keys are the grouping criteria, and the values are the grouped elements.


Steps to Use groupingBy

Prepare Your Data: Have a Collection or Stream of elements (e.g., a List of objects).


Stream Your Data: Convert your collection into a stream using .stream().


Group Elements:


Use Collectors.groupingBy() to specify how the elements should be grouped.


Optionally, apply downstream collectors for further aggregation (e.g., counting(), mapping()).


Examples 1 : Group by String length 


import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


public class GroupingByExample {

    public static void main(String[] args) {

        // Sample data

        List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");


        // Group words by their length

        Map<Integer, List<String>> groupedByLength = words.stream()

                .collect(Collectors.groupingBy(String::length));


        // Output the result

        System.out.println("Grouped by Length: " + groupedByLength);

    }

}

Output:

Grouped by Length: {3=[fig], 4=[date], 5=[apple, grape], 6=[banana, cherry]}


Explanation:


String::length is the classifier function that groups the words by their length.


The result is a Map where the key is the word length, and the value is a list of words with that length.


Exmaple 2: Group employee by department 


import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


class Employee {

    String name;

    String department;


    Employee(String name, String department) {

        this.name = name;

        this.department = department;

    }


    @Override

    public String toString() {

        return name;

    }

}


public class GroupingByExample {

    public static void main(String[] args) {

        // Sample data

        List<Employee> employees = Arrays.asList(

                new Employee("Alice", "HR"),

                new Employee("Bob", "IT"),

                new Employee("Charlie", "HR"),

                new Employee("David", "Finance"),

                new Employee("Eve", "IT")

        );


        // Group employees by department

        Map<String, List<Employee>> groupedByDepartment = employees.stream()

                .collect(Collectors.groupingBy(employee -> employee.department));


        // Output the result

        System.out.println("Grouped by Department: " + groupedByDepartment);

    }

}


output:

Grouped by Department: {Finance=[David], HR=[Alice, Charlie], IT=[Bob, Eve]}


Explanation:

The classifier function is employee -> employee.department, which groups employees by their department.


The result is a Map where the key is the department, and the value is a list of employees in that department.


Example 3: Group and Count Elements


import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


public class GroupingByCounting {

    public static void main(String[] args) {

        // Sample data

        List<String> items = Arrays.asList("apple", "banana", "apple", "orange", "banana", "apple");


        // Group and count occurrences

        Map<String, Long> itemCounts = items.stream()

                .collect(Collectors.groupingBy(item -> item, Collectors.counting()));


        // Output the result

        System.out.println("Item Counts: " + itemCounts);

    }

}


Output:

Item Counts: {orange=1, banana=2, apple=3}


Explanation:

The classifier function is item -> item, grouping elements by their value.


The downstream collector Collectors.counting() counts the occurrences of each group.


Key Features of groupingBy

Basic Grouping:


Groups elements based on a key or classifier.


E.g., Collectors.groupingBy(Function.identity()).


Downstream Collectors:


Apply further operations like counting, mapping, or reducing on the grouped elements.


Example: Collectors.groupingBy(key, Collectors.counting()).


Nested Grouping:


Group by multiple levels using nested groupingBy.


Example: Group employees by department and then by job title.


Custom Map Implementation:


Use the three-argument version of groupingBy to specify the type of Map to use for the result.



Nested grouping with groupingBy in Java 8 allows you to group elements by multiple levels. This involves creating a Map where each key corresponds to a group, and the value is another map representing the next level of grouping. Here’s how to achieve this with some examples:


Example 1: Group Employees by Department and then by Designation

java



Pimport java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


class Employee {

    String name;

    String department;

    String designation;


    Employee(String name, String department, String designation) {

        this.name = name;

        this.department = department;

        this.designation = designation;

    }


    @Override

    public String toString() {

        return name;

    }

}


public class NestedGroupingExample {

    public static void main(String[] args) {

        // Sample data

        List<Employee> employees = Arrays.asList(

            new Employee("Alice", "HR", "Manager"),

            new Employee("Bob", "IT", "Developer"),

            new Employee("Charlie", "HR", "Executive"),

            new Employee("David", "IT", "Developer"),

            new Employee("Eve", "Finance", "Analyst")

        );


        // Nested grouping by department and then by designation

        Map<String, Map<String, List<Employee>>> groupedByDeptAndDesignation = employees.stream()

            .collect(Collectors.groupingBy(

                emp -> emp.department, // First level grouping: by department

                Collectors.groupingBy(

                    emp -> emp.designation // Second level grouping: by designation

                )

            ));


        // Print the result

        System.out.println("Grouped by Department and Designation: " + groupedByDeptAndDesignation);

    }

}

Output:


Grouped by Department and Designation: {

    HR={Manager=[Alice], Executive=[Charlie]},

    IT={Developer=[Bob, David]},

    Finance={Analyst=[Eve]}

}



Explanation:


The first groupingBy groups employees by their department.


The second groupingBy further groups employees by their designation within each department.


The result is a nested Map<String, Map<String, List<Employee>>>.


Example 2: Group Words by Length and then by Their Initial Character


import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


public class NestedGroupingWords {

    public static void main(String[] args) {

        // Sample data

        List<String> words = Arrays.asList("apple", "ant", "banana", "cherry", "cat", "dog", "dragonfruit");


        // Nested grouping by word length and then by the first character

        Map<Integer, Map<Character, List<String>>> groupedByLengthAndFirstChar = words.stream()

            .collect(Collectors.groupingBy(

                String::length, // First level grouping: by length of the word

                Collectors.groupingBy(

                    word -> word.charAt(0) // Second level grouping: by the first character

                )

            ));


        // Print the result

        System.out.println("Grouped by Length and First Character: " + groupedByLengthAndFirstChar);

    }

}

Output:


Grouped by Length and First Character: {

    3={a=[ant], c=[cat], d=[dog]},


    5={a=[apple]},

    6={b=[banana]},

    7={c=[cherry]},

    11={d=[dragonfruit]}

}

Explanation:


The first groupingBy groups words by their length.


The second groupingBy groups words within each length group by their first character.








No comments:

Post a Comment