Main Tutorials

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 Author

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

Comments

Subscribe
Notify of
44 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Romain Gervais
8 years ago

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.

Sanjay
6 years ago
Reply to  Romain Gervais

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

Zachary Rudzik
5 years ago
Reply to  Sanjay

Nope!

mkyong
8 years ago
Reply to  Romain Gervais

Thanks for the “method references” example.

KROY
6 years ago

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

Allen Zhang
5 years ago
Reply to  KROY

You may want to convert it to empty string by StringUtils before comparison or capture the exception in the wrapper code.

Kisna
3 years ago
Reply to  Allen Zhang

humans.sort((h1, h2) -> {
if (h1 == null) {
return h2 == null ? 0 : 1;
}
else if (h2 == null) {
return -1;
}
return h1.getName().compareTo(h2.getName());
});

venkatesh
5 years ago

from where we will get Develpoer class?
I am getting exception “Developer cannot be resolved to a type”.

Avisek Das
4 years ago
Reply to  venkatesh

package com.avi.lamda;

import java.math.BigDecimal;

public class Developer {
private String name;
private BigDecimal salary;
private int age;
public Developer(String name, BigDecimal salary, int age) {

this.name=name;
this.salary=salary;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

public String toString() {
return name+” “+salary+” “+age;
}
}

CoderBoy
4 years ago
Reply to  Avisek Das

Keeping data members private and trying to use comparator (lambda or otherwise) is not going to work as it won’t be able to access the private field. Either make them public or default, or implement Comparable and override compareTo.

diego
2 years ago
Reply to  CoderBoy

it works with private too!!

Navneet
6 years ago

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

Lars
6 years ago

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

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

chirag visavadia
8 years ago

Very good explaination, simple and straight farward! Thanks

Halil ?braihm KÜLEY
8 years ago

very good 🙂

eee
2 years ago

I love this color scheme fo idea intellij. What is the name of it?

diego
2 years ago

Sempre mandando muito!!!! Valeu Mkyong!!!

Manh Nguyen
3 years ago

Hi Mkyong, We can sort getAge max to min??

Kammiti Krishna
4 years ago

I did not find my comment.

Kammiti Krishna
4 years ago

Hi Mkyong,
Can we sort multiple fields at a time using lambdas, if it is please share me the example.

arun
4 years ago

Below code is also use for sorting
Collections.sort(developerList, Comparator.comparing(Developer::getAge));

abcd
4 years ago

Sorry brother i mean classes are not properly organize missed dependency class file in some of your articles. You article are great, but if you can organize the java code in proper place it would be great. Thank you so much for sharing.

abcd
4 years ago

not properly organize missed dependency file. You article is good but Please post in organize manager

virendra
6 years ago

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

t.start();

InExperience
6 years ago

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

Vaibhav Thapliyal
6 years ago

Well Explained!

anurag
6 years ago

very nice thanks

charan
6 years ago

awesome post….thank you soo much

anurag
6 years ago

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

bala
6 years ago

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
6 years ago
Reply to  bala

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

deano7000
7 years ago

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
7 years ago

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

infoj
8 years ago

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

Maciej Szarli?ski
8 years ago

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
8 years ago

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

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

Moayad
6 years ago
Reply to  mkyong

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

Maciej Szarli?ski
8 years ago
Reply to  mkyong

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

Kishan B
7 years ago

Thanks.. Very good info on Comparator.comparing !

Rajeev Ranjan
6 years ago

nice article

Carol
7 years ago

very clear

omar
8 years ago

thanks mkyong for this article,
java projects source code .

java_an
8 years ago

nice one post myyong and visit also java8 program examples

Tabrez
5 years ago
Reply to  java_an

nice