Pages

Monday, December 6, 2021

Java 8 Comparator Lambda Examples

1. Overview


In this tutorial, We'll learn how to use the Comparator interface with lambda expression in Java 8 onwards.

Lambda expression is to replace the anonymous implementations and to reduce the boilerplate code.

This makes the code cleaner and focus more on the business logic rather than semantics.


Java community provided a few sets of rules and guidelines in creating the lambda statements.

Lambda syntax and invalid one are discussed in detail in the previous discussions "java 8 lambda expressions".

First, we will see the examples without lambda and then the next section will see the equivalent lambdas.

For sorting to work with lambda comparator, we have to use the Collections.sort() method.

Java Comparator Lambda Examples



2. Usage of Java Comparator Without Lambda


Comparator in Java is an interface that is used to sort the collections based on the custom objects fields.

The comparator must be used with the combination of List or Set or Queue implementations.

Here the comparator creation is called an Anonymous comparator.

2.1 Sort Engineers by int id


Simple example 1
package com.javaprogramto.java8.comparator.lambda;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

public class WIthoutLambdasExample {

	public static void main(String[] args) {

		List<Engineer> engineers1 = getEngineersList();

		// printing engineer objects sorted by id
		System.out.println("Before sorting");
		engineers1.forEach(System.out::println);

		// comparator before java 8 and without lambds
		Comparator<Engineer> idComparator = new Comparator<Engineer>() {

			@Override
			public int compare(Engineer e1, Engineer e2) {

				return Integer.valueOf(e1.getId()).compareTo(e2.getId());
			}
		};

		// sorting with collections.sort()
		Collections.sort(engineers1, idComparator);

		// printing engineer objects sorted by id
		System.out.println("\nAfter sorting");
		engineers1.forEach(System.out::println);

	}

	private static List<Engineer> getEngineersList() {
		// creating the List of engineers
		List<Engineer> engineers = new LinkedList<>();

		// adding engineer objects
		engineers.add(new Engineer(100, "Jeo", 100000, false));
		engineers.add(new Engineer(103, "Sunny", 500000, true));
		engineers.add(new Engineer(104, "Zeon", 300000, false));
		engineers.add(new Engineer(105, "Neon", 400000, true));
		engineers.add(new Engineer(102, "Ammon", 200000, false));

		return engineers;
	}

}

class Engineer {

	private int id;
	private String name;
	private long salary;
	private boolean fullTime;

	public Engineer(int id, String name, long salary, boolean fullTime) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
		this.fullTime = fullTime;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public long getSalary() {
		return salary;
	}

	public void setSalary(long salary) {
		this.salary = salary;
	}

	public boolean isFullTime() {
		return fullTime;
	}

	public void setFullTime(boolean fullTime) {
		this.fullTime = fullTime;
	}

	@Override
	public String toString() {
		return "Engineer [id=" + id + ", name=" + name + ", salary=" + salary + ", fullTime=" + fullTime + "]";
	}
}

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]


2.2 Sort Engineers by string name



Example 2
// sort engineers by name

List<Engineer> engineers2 = getEngineersList();

// printing engineer objects sorted by id
System.out.println("Before sorting");
engineers2.forEach(System.out::println);

// comparator before java 8 and without lambds
Comparator<Engineer> nameComparator = new Comparator<Engineer>() {

	@Override
	public int compare(Engineer e1, Engineer e2) {

		return e1.getName().compareTo(e2.getName());
	}
};

// sorting with collections.sort()
Collections.sort(engineers2, nameComparator);

// printing engineer objects sorted by id
System.out.println("\nAfter sorting");
engineers2.forEach(System.out::println);

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]


2.3 Sort Engineers by Long Salary


Example 3
// sort engineers by salary

List<Engineer> engineers3 = getEngineersList();

// printing engineer objects sorted by id
System.out.println("\nEngieer Sort by Salary");
System.out.println("\nBefore sorting");
engineers3.forEach(System.out::println);

// comparator before java 8 and without lambds
Comparator<Engineer> salaryComparator = new Comparator<Engineer>() {

	@Override
	public int compare(Engineer e1, Engineer e2) {

return Long.valueOf(e1.getSalary()).compareTo(e2.getSalary());
	}
};

// sorting with collections.sort()
Collections.sort(engineers3, salaryComparator);

// printing engineer objects sorted by id
System.out.println("\nAfter sorting");
engineers3.forEach(System.out::println);

Output
Engieer Sort by Salary

Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]


2.4 Sort Engineers by Boolean  FullTime


Example 4
// sort engineers by full time

List<Engineer> engineers4 = getEngineersList();

// printing engineer objects sorted by id
System.out.println("\nEngieer Sort by fulltime");
System.out.println("\nBefore sorting");
engineers4.forEach(System.out::println);

// comparator before java 8 and without lambds
Comparator<Engineer> fulltimeComparator = new Comparator<Engineer>() {

	@Override
	public int compare(Engineer e1, Engineer e2) {

return Boolean.valueOf(e1.isFullTime()).compareTo(Boolean.valueOf(e2.isFullTime()));
	}
};

// sorting with collections.sort()
Collections.sort(engineers4, fulltimeComparator);

// printing engineer objects sorted by id
System.out.println("\nAfter sorting");
engineers4.forEach(System.out::println);

Output
Engieer Sort by fulltime

Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]


3. Usage Lambda With Java Comparator


By using lambda, we can reduce code and make focusing much on core logic. 

Lambda is indicated with the arrow symbol (->). Look at the below syntax

(datatype variable1,datatype variable2, ..) -> { logic }


Here the data types are optional and no need to use the return statement inside the lambda body if there is only one statement.

When working with lambda or java 8 then you do not need to go with the Collections.sort() method.
because java 8 list is added with the sort() method directly. So, we can call list.sort() with the comparator instance or lambda.

3.1 Compartor sort by id with Lambda


below is the complete example with Lambda and list.sort() to sort the list of engineers by id in ascending order.



Example 5
public class WithLambdasExample {

	public static void main(String[] args) {

		List<Engineer> engineers1 = getEngineersList();

		// printing engineer objects sorted by id
		System.out.println("Before sorting");
		engineers1.forEach(System.out::println);

		// comparator with lambdas
		Comparator<Engineer> idComparator = (e1, e2) -> Integer.valueOf(e1.getId()).compareTo(e2.getId()); 

		// sorting with list.sort()
		engineers1.sort(idComparator);

		// printing engineer objects sorted by id
		System.out.println("\nAfter sorting");
		engineers1.forEach(System.out::println);

	}

	private static List<Engineer> getEngineersList() {
		// creating the List of engineers
		List<Engineer> engineers = new LinkedList<>();

		// adding engineer objects
		engineers.add(new Engineer(100, "Jeo", 100000, false));
		engineers.add(new Engineer(103, "Sunny", 500000, true));
		engineers.add(new Engineer(104, "Zeon", 300000, false));
		engineers.add(new Engineer(105, "Neon", 400000, true));
		engineers.add(new Engineer(102, "Ammon", 200000, false));

		return engineers;
	}

}

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]

3.2 Compartor sort by name with Lambda


Example 6
// comparator in java 8 with lambdas
Comparator<Engineer> nameComparator = (e1, e2) -> e1.getName().compareTo(e2.getName());

// sorting with list.sort()
engineers2.sort(nameComparator);

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]

3.3 Compartor sort by salary with Lambda


Example 7
// comparator in java 8 with lambds
Comparator<Engineer> salaryComparator = (e1, e2) -> Long.valueOf(e1.getSalary()).compareTo(e2.getSalary());

// sorting with list.sort()
engineers3.sort(salaryComparator);

Output
Engieer Sort by Salary

Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]

3.4 Comparator sort by full time with Lambda


Example 8
// comparator in java 8 with lambdas
Comparator<Engineer> fulltimeComparator = (e1, e2) -> Boolean.valueOf(e1.isFullTime()).compareTo(Boolean.valueOf(e2.isFullTime()));

// sorting with list.sort()
engineers4.sort(fulltimeComparator);

Output
Engieer Sort by fulltime

Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]

4. Java 8 Comparator with Lambda sorting by multiple fields


The below example is to sort based on the full time and id.

First, create two separate comparators with lambda by full time and id.

Next, call thenComparint() method on the full-time comparator as below.


Example 9
Comparator<Engineer> fullTimeAndIdComparator = fulltimeComparator.thenComparing(idComparator);

This creates a new comparator with by full time and id fields together.

Look at the full code for multiple fields.

Full Example
public class WithLambdasExample2 {

	public static void main(String[] args) {

		List<Engineer> engineers1 = getEngineersList();

		// printing engineer objects sorted by id
		System.out.println("Before sorting");
		engineers1.forEach(System.out::println);

		// comparator with lambdas
		Comparator<Engineer> fulltimeComparator = (e1, e2) -> Boolean.valueOf(e1.isFullTime())
				.compareTo(Boolean.valueOf(e2.isFullTime()));

		Comparator<Engineer> idComparator = (e1, e2) -> Integer.valueOf(e1.getId()).compareTo(e2.getId());

		Comparator<Engineer> fullTimeAndIdComparator = fulltimeComparator.thenComparing(idComparator);

		// sorting with collections.sort()
		engineers1.sort(fullTimeAndIdComparator);

		// printing engineer objects sorted by id
		System.out.println("\nAfter sorting");
		engineers1.forEach(System.out::println);

	}
}

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]


5. Java 8 Comparator with Lambda Sorting in reverse order or descending order


To get sorted the objects with comparator by reverse order and objects in the descending order.

For the descending order, after creating the Comparator with lambda then you need to call reversed() method of Comparator as below.

Example 10
Comparator<Engineer> fullTimeAndIdComparator = fulltimeComparator.thenComparing(idComparator).reversed();

// sorting with collections.sort()
engineers1.sort(fullTimeAndIdComparator);

// printing engineer objects sorted by id
System.out.println("\nAfter sorting");
engineers1.forEach(System.out::println);

Output
Before sorting
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]

After sorting
Engineer [id=105, name=Neon, salary=400000, fullTime=true]
Engineer [id=103, name=Sunny, salary=500000, fullTime=true]
Engineer [id=104, name=Zeon, salary=300000, fullTime=false]
Engineer [id=102, name=Ammon, salary=200000, fullTime=false]
Engineer [id=100, name=Jeo, salary=100000, fullTime=false]

Compare this output with the above section output for the reversed order.


6. Conclusion


In this article, We've seen how to use lambda with comparator in java 8.



No comments:

Post a Comment

Please do not add any spam links in the comments section.