In this example, we will show you how to use Java 8 Lambda expression to write a Comparator to sort a List.
1. Classic Comparator example.
Comparator<Developer> byName = new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getName().compareTo(o2.getName());
}
};
2. Lambda expression equivalent.
Comparator<Developer> byName = (Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());
Developer.java
package com.favtuts.java8;
import java.math.BigDecimal;
public class Developer {
@Override
public String toString() {
return "Developer [" +
" name='" + getName() + "'" +
", salary='" + getSalary() + "'" +
", age='" + getAge() + "'" +
"]";
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public BigDecimal getSalary() {
return this.salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Developer(String name, int age, BigDecimal salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
private String name;
private int age;
private BigDecimal salary;
}
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.favtuts.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<Developer> listDevs = getDevelopers();
System.out.println("Before Sort");
for (Developer developer : listDevs) {
System.out.println(developer);
}
// sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
@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<Developer> getDevelopers() {
List<Developer> result = new ArrayList<Developer>();
result.add(new Developer("favtuts", 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='favtuts', 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='favtuts', 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<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getAge() - o2.getAge();
}
});
//sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getName().compareTo(o2.getName());
}
});
//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
@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<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o2.getAge() - o1.getAge();
}
});
Lambda expression example :
TestSorting.java
package com.favtuts.java8;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class TestSorting {
public static void main(String[] args) {
List<Developer> 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<Developer> getDevelopers() {
List<Developer> result = new ArrayList<Developer>();
result.add(new Developer("favtuts", 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='favtuts', 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='favtuts', 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<Developer>() {
@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<Developer>() {
@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<Developer>() {
@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<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator);
Output
Developer [ name='favtuts', 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<Developer> 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='favtuts', salary='70000', age='33']
Download Source Code
$ git clone https://github.com/favtuts/java-core-tutorials-examples
$ cd java-basic/java8