Sunday, April 2, 2017

Java8 streams and lambda expression GroupBy MaxBy MinBy Example

package com.company.samples;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
public class Java8GroupByMaxByMinByExample {
public static void main (String[] args) {
Student s1 = new Student ("Shyam", 22, "A");
Student s2 = new Student ("Ram", 23, "A");
Student s3 = new Student ("Mohan", 22, "B");
Student s4 = new Student ("Ramesh", 21, "B");
List<Student> list = Arrays.asList (s1, s2, s3, s4);
Comparator<Student> ageComparator = Comparator.comparing (Student::getAge);
//Find eldest student in each class and group by class
Map<String, Optional<Student>> eldestByClass = list.stream ().
collect (groupingBy (Student::getClassName, Collectors.reducing (BinaryOperator.maxBy (ageComparator))));
//Group students by classname
Map<String, List<Student>> studentsByClass = list.stream ()
.collect (groupingBy (s -> s.getClassName ()));
//Group students by age for each class
Map<String, List<Integer>> studentAgesByClass = list.stream ()
.collect (groupingBy (st -> st.getClassName (), mapping ((Student s) -> s.getAge (), toList ())));
//Group students by classname
Map<String, List<String>> studentNamesByClass = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping ((Student s) -> s.getName (), toList ())));
//another syntax -1
Map<String, List<String>> studentNamesByClass2 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (s -> s.getClassName (), toList ())));
//another syntax -2
Map<String, List<String>> studentNamesByClass3 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (Student::getClassName, toList ())));
//another syntax -3 use set instead of List to eliminate duplications
Map<String, Set<String>> studentNamesByClass4 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (Student::getClassName, toSet ())));
//Find youngest student in each class and group by class
Map<String, Optional<Student>> youngestByClass = list.stream ().collect (groupingBy (Student::getClassName,
Collectors.reducing (BinaryOperator.minBy (ageComparator))));
}
}
class Student {
private String name;
private int age;
private String className;
public Student (String name, int age, String className) {
this.name = name;
this.age = age;
this.className = className;
}
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
public int getAge () {
return age;
}
public void setAge (int age) {
this.age = age;
}
public String getClassName () {
return className;
}
public void setClassName (String className) {
this.className = className;
}
}