Java 8 Lambda : Comparator example

java-lambda-expression

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());

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.mkyong.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("mkyong", 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=mkyong, 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=mkyong, 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.mkyong.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("mkyong", 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=mkyong, 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=mkyong, 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=mkyong, 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=mkyong, salary=70000, age=33]

References

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

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
KROY
Guest
KROY

what if there is a null value? These examples is not handling null scenarios.

Romain Gervais
Guest
Romain Gervais

Hi,

In Java 8 you could print the list of developers like this :
listDevs.forEach(System.out::println);

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

Romain.

mkyong
Guest
mkyong

Thanks for the “method references” example.

Sanjay
Guest
Sanjay

i could format my output like below say if my list is “Integers” (list having 100,10,222,3000,40000)

i can use
listInts.forEach((i)->System.out.println(i+”,”));

using method references all integers will be appended and displayed, but can i use “,” as above using method references

?? – any idea

Lars
Guest
Lars

The lambda comparator example can be simplified slightly by omitting the class declaration:

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

Maciej Szarli?ski
Guest
Maciej Szarli?ski

Actually, we can do it even simplier. Instead of writing for example

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

you can shorten this using “comparing” factory method combined with method reference:

listDevs.sort(Comparator.comparing(Developer::getSalary()).reversed());

after static import:

listDevs.sort(comparing(Developer::getSalary()).reversed());

mkyong
Guest
mkyong

Thanks for your example, The “()” from getSalary() will prompts error, just remove it.

listDevs.sort(Comparator.comparing(Developer::getSalary));

Maciej Szarli?ski
Guest
Maciej Szarli?ski

Yes of course, I have meant method reference, not a method call, there. Sorry for mistake.

Kishan B
Guest
Kishan B

Thanks.. Very good info on Comparator.comparing !

Moayad
Guest
Moayad

how I’m gonna reach the sub attribute of Salary in case of Salary is another class?

virendra
Guest
virendra

User below code
Thread t = new Thread(() -> System.out.println());

t.start();

InExperience
Guest
InExperience

Is it possible to have the complete list of files by link? Because following your tutorial I have a lot of problem, thanks

Rajeev Ranjan
Guest
Rajeev Ranjan

nice article

Navneet
Guest
Navneet

Hi Mkyong, thanks for this article. You explained it very well

Vaibhav Thapliyal
Guest
Vaibhav Thapliyal

Well Explained!

anurag
Guest
anurag

very nice thanks

charan
Guest
charan

awesome post….thank you soo much

anurag
Guest
anurag

nice article and example is also very clear and simple
thank you for this awesome post

bala
Guest
bala

I am not able get the output as mentioned here (sorting with out lambada)
I have complied and executed above program in eclipse mar and the output is
Before Sort
javatpointegs.Comparatoreg$Developer@15db9742
javatpointegs.Comparatoreg$Developer@6d06d69c
javatpointegs.Comparatoreg$Developer@7852e922
javatpointegs.Comparatoreg$Developer@4e25154f
After Sort
javatpointegs.Comparatoreg$Developer@15db9742
javatpointegs.Comparatoreg$Developer@6d06d69c
javatpointegs.Comparatoreg$Developer@7852e922
javatpointegs.Comparatoreg$Developer@4e25154f

Bogdan
Guest
Bogdan

this can happen if you do not override toString() method in Developer class.

deano7000
Guest
deano7000

I find that I keep coming back here, because your Java 8 examples are the best. You keep it simple and focused, much more so than the other examples out there.

PON
Guest
PON

Got me too long to find information like this on other sites until I reached this article. Thanks, very informative :)

infoj
Guest
infoj

Here Lambda expression can be used to implement comparator because Comparator is a Functional Interface. Lambda expression provides implementation of the functional interface.

See some of the Lambda expression examples here – http://netjs.blogspot.in/2015/06/lambda-expression-examples-in-java-8.html

Read about functional interface here – http://netjs.blogspot.in/2015/06/functional-interfaces-and-lambda-expression-in-java-8.html

omar
Guest
omar

thanks mkyong for this article,
java projects source code .

chirag visavadia
Guest
chirag visavadia

Very good explaination, simple and straight farward! Thanks

Halil ?braihm KÜLEY
Guest
Halil ?braihm KÜLEY

very good :)

Carol
Guest
Carol

very clear

java_an
Guest
java_an

nice one post myyong and visit also java8 program examples