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