Sunday, 30 August 2015

Java 8 Lambda : Comparator example

In this example, we will show you how to use Java 8 Lambda expression to write a Comparator to sort a List.

Classic Comparator example:

 Comparator byName = new Comparator() { 
 
    @Override
    public int compare(Developer o1, Developer o2) {
                return o1.getName().compareTo(o2.getName());   
    
 
};

Lambda expression equivalent:

 Comparator byName = (Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());

1. Sort without Lambda

Example to compare the Developer objects using their age. Normally, you use Collections.sort and pass an anonymous Comparator class like this :

TestSorting.java
package com.naidu.java8;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;
public class TestSorting {
 public static void main(String[] args) {

  List listDevs = getDevelopers();

  System.out.println("Before Sort");

  for (Developer developer : listDevs) {

   System.out.println(developer);

  }


  //sort by age

  Collections.sort(listDevs, new Comparator() {

   @Override

   public int compare(Developer o1, Developer o2) {

    return o1.getAge() - o2.getAge();

   }

  });


  System.out.println("After Sort");

  for (Developer developer : listDevs) {

   System.out.println(developer);

  }

 

 }

 private static List getDevelopers() {

  List result = new ArrayList();

  result.add(new Developer("naidu", new BigDecimal("70000"), 33));

  result.add(new Developer("alvin", new BigDecimal("80000"), 20));

  result.add(new Developer("jason", new BigDecimal("100000"), 10));

  result.add(new Developer("iris", new BigDecimal("170000"), 55));

 

  return result;

 }

}

OUTPUT
Before Sort

Developer [name=naidu, salary=70000, age=33]

Developer [name=alvin, salary=80000, age=20]

Developer [name=jason, salary=100000, age=10]

Developer [name=iris, salary=170000, age=55]



After Sort

Developer [name=jason, salary=100000, age=10]

Developer [name=alvin, salary=80000, age=20]

Developer [name=naidu, salary=70000, age=33]

Developer [name=iris, salary=170000, age=55]


When the sorting requirement is changed, you just pass in another new anonymous Comparator class :
 //sort by age

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getAge() - o2.getAge();

  }

 });


 //sort by name

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getName().compareTo(o2.getName());

  }

 });

   

 //sort by salary

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getSalary().compareTo(o2.getSalary());

  }

 });   


It works, but, do you think it is a bit weird to create a class just because you want to change a single line of code?

2. Sort with Lambda

In Java 8, the List interface is supports the sort method directly, no need to use Collections.sort anymore.

 //List.sort() since Java 8

 listDevs.sort(new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o2.getAge() - o1.getAge();

  }

 });

Lambda expression example :

TestSorting.java
package com.naidu.java8;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.List;

public class TestSorting {

 public static void main(String[] args) {

  List listDevs = getDevelopers();

  System.out.println("Before Sort");

  for (Developer developer : listDevs) {

   System.out.println(developer);

  }

  System.out.println("After Sort");


  //lambda here!

  listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());


  //java 8 only, lambda also, to print the List

  listDevs.forEach((developer)->System.out.println(developer));

 }


 private static List getDevelopers() {
  List result = new ArrayList();

  result.add(new Developer("naidu", new BigDecimal("70000"), 33));

  result.add(new Developer("alvin", new BigDecimal("80000"), 20));

  result.add(new Developer("jason", new BigDecimal("100000"), 10));

  result.add(new Developer("iris", new BigDecimal("170000"), 55));


  return result;

 }

}

OUTPUT
Before Sort

Developer [name=naidu, salary=70000, age=33]

Developer [name=alvin, salary=80000, age=20]

Developer [name=jason, salary=100000, age=10]

Developer [name=iris, salary=170000, age=55]



After Sort

Developer [name=jason, salary=100000, age=10]

Developer [name=alvin, salary=80000, age=20]

Developer [name=naidu, salary=70000, age=33]

Developer [name=iris, salary=170000, age=55]

3. More Lambda Examples

3.1 Sort By age

 //sort by age

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getAge() - o2.getAge();

  }

 });


 //lambda

 listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());


 //lambda, valid, parameter type is optional

 listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());

3.2 Sort by name

 //sort by name

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getName().compareTo(o2.getName());

  }

 });

 

 //lambda

 listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName())); 



 //lambda

 listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName())); 

3.3 Sort by salary

 //sort by salary

 Collections.sort(listDevs, new Comparator() {

  @Override

  public int compare(Developer o1, Developer o2) {

   return o1.getSalary().compareTo(o2.getSalary());

  }

 });   


 //lambda

 listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));


 //lambda

 listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));

3.4 Reversed sorting.

3.4.1 Lambda expression to sort a List using their salary.

 Comparator salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());

 listDevs.sort(salaryComparator);

OUTPUT
Developer [name=naidu, salary=70000, age=33]

Developer [name=alvin, salary=80000, age=20]

Developer [name=jason, salary=100000, age=10]

Developer [name=iris, salary=170000, age=55]

3.4.2 Lambda expression to sort a List using their salary, reversed order.

 Comparator salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());

 listDevs.sort(salaryComparator.reversed());
OUTPUT
Developer [name=iris, salary=170000, age=55]

Developer [name=jason, salary=100000, age=10]

Developer [name=alvin, salary=80000, age=20]

Developer [name=naidu, salary=70000, age=33]



References
  1. Start Using Java Lambda Expressions
  2. Oracle : Lambda Expressions
  3. Oracle : Comparator

0 comments:

Post a comment

Contact

Get in touch with me


Adress/Street

Bangalore, India