Friday 17 July 2015

Java8: Group By implementation in java

If you are familiar with GROUP BY, ORDER BY clauses in MySQL, don’t you think that why java don’t provide any function to group collection of objects. Until java8, you have to write your own implementation to group collection of objects based on their properties. Good news with java8 is, you no need to implement GROUP BY functionality. Java8 provides ‘Collectors.groupingBy’ method to group objects.

In this post, you are going to learn how to group collection of employee objects based on their properties.

Group objects in Java8
Lets say I had employee object with fields id, firstName, lastName, age and city. ‘employees’ contain list of employee objects.

To group employee by city
Map<String, List<Employee>> groupByCity = employees.stream().collect(Collectors.groupingBy(Employee::getCity));

To group employees by age
Map<Integer, List<Employee>> groupByAge = employees.stream().collect(Collectors.groupingBy(Employee::getAge));

To group employees on multiple properties
You can achieve this by chaining groupingBy collectors. For example, following statement group employees by city and age.
Map<String, Map<Integer, List<Employee>>> groupByCityAndAge = employees.stream().collect(Collectors.groupingBy(Employee::getCity,Collectors.groupingBy(Employee::getAge)));

import java.util.Objects;

public class Employee {
 private int id;
 private String firstName;
 private String lastName;
 private int age;
 private String city;

 public Employee(int id, String firstName, String lastName, int age,
   String city) {
  super();
  this.id = id;
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.city = city;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 @Override
 public boolean equals(Object employee) {
  if (Objects.isNull(employee))
   return false;

  if (!(employee instanceof Employee))
   return false;

  Employee emp = (Employee) employee;

  return id == emp.id;
 }

 @Override
 public int hashCode() {
  return Objects.hash(id, firstName, lastName, age);
 }

 @Override
 public String toString() {
  return String.format("%s(%s,%d)", firstName, city, age);
 }

}

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupByEx {

 public static String stars = "***************************************";

 public static void main(String args[]) {
  Employee emp1 = new Employee(1, "Hari Krishna", "Gurram", 26,
    "Bangalore");
  Employee emp2 = new Employee(2, "Joel", "Chelli", 27, "Hyderabad");
  Employee emp3 = new Employee(3, "Shanmukh", "Kummary", 28, "Chennai");
  Employee emp4 = new Employee(4, "Harika", "Raghuram", 27, "Chennai");
  Employee emp5 = new Employee(5, "Sudheer", "Ganji", 27, "Bangalore");
  Employee emp6 = new Employee(6, "Rama Krishna", "Gurram", 27,
    "Bangalore");
  Employee emp7 = new Employee(7, "PTR", "PTR", 27, "Hyderabad");
  Employee emp8 = new Employee(8, "Siva krishna", "Ponnam", 28,
    "Hyderabad");
  Employee emp9 = new Employee(9, "Surendra", "Kumar", 28, "Hyderabad");
  Employee emp10 = new Employee(10, "Pradeep", "Kumar", 39, "Chennai");
  Employee emp11 = new Employee(11, "Sharief", "Khan", 30, "Bangalore");

  List<Employee> employees = new ArrayList<>();

  employees.add(emp1);
  employees.add(emp2);
  employees.add(emp3);
  employees.add(emp4);
  employees.add(emp5);
  employees.add(emp6);
  employees.add(emp7);
  employees.add(emp8);
  employees.add(emp9);
  employees.add(emp10);
  employees.add(emp11);

  Map<String, List<Employee>> groupByCity = employees.stream().collect(
    Collectors.groupingBy(Employee::getCity));

  Map<Integer, List<Employee>> groupByAge = employees.stream().collect(
    Collectors.groupingBy(Employee::getAge));

  Map<String, Map<Integer, List<Employee>>> groupByCityAndAge = employees
    .stream().collect(
      Collectors.groupingBy(Employee::getCity,
        Collectors.groupingBy(Employee::getAge)));

  System.out.println("Group By city");
  System.out.println(groupByCity);
  System.out.println("\n");

  System.out.println("Group By age");
  System.out.println(groupByAge);
  System.out.println("\n");

  System.out.println("Group By city and age");
  System.out.println(groupByCityAndAge);

 }
}


Output
Group By city
{Chennai=[Shanmukh(Chennai,28), Harika(Chennai,27), Pradeep(Chennai,39)], Hyderabad=[Joel(Hyderabad,27), PTR(Hyderabad,27), Siva krishna(Hyderabad,28), Surendra(Hyderabad,28)], Bangalore=[Hari Krishna(Bangalore,26), Sudheer(Bangalore,27), Rama Krishna(Bangalore,27), Sharief(Bangalore,30)]}


Group By age
{39=[Pradeep(Chennai,39)], 26=[Hari Krishna(Bangalore,26)], 27=[Joel(Hyderabad,27), Harika(Chennai,27), Sudheer(Bangalore,27), Rama Krishna(Bangalore,27), PTR(Hyderabad,27)], 28=[Shanmukh(Chennai,28), Siva krishna(Hyderabad,28), Surendra(Hyderabad,28)], 30=[Sharief(Bangalore,30)]}


Group By city and age
{Chennai={39=[Pradeep(Chennai,39)], 27=[Harika(Chennai,27)], 28=[Shanmukh(Chennai,28)]}, Hyderabad={27=[Joel(Hyderabad,27), PTR(Hyderabad,27)], 28=[Siva krishna(Hyderabad,28), Surendra(Hyderabad,28)]}, Bangalore={26=[Hari Krishna(Bangalore,26)], 27=[Sudheer(Bangalore,27), Rama Krishna(Bangalore,27)], 30=[Sharief(Bangalore,30)]}}





No comments:

Post a Comment