Hello Java programmers, you may know that the JDK 8 has added a lot of
new methods into the Comparator interface which makes comparing and
sorting objects in Java really easy. Two such methods are called
comparing() and
thenComparing() which was added
in the
java.util.Comparator interface.
These methods accept a key extractor function and return a Comparator that
can compare to that key. The key must be
Comparable though like String, Integer, or any Java class which implements
java.lang.Comparable interface,
I mean the key must implement Comparable interface.
Both comparing() and
thenComparing() allows you to
easily compare objects on any field as well as compare them on multiple
fields by chaining comparators. As the name suggests, you can use the
thenComparing() method to chain
comparators to compare objects on multiple fields and multiple
orders.
For example, you can use comparing() and thenComparing() to compare Book
objects first on author and then price. you can also choose to sort on
increasing order of price of decreasing order of price.
Overall these new Comparator methods make comparing objects really easy
and fun as you can also pass both
lambda expression
and
method reference
to this method, making it super easy to write custom Comparators on the
fly as shown in the following example but before that let's create a
custom Java object or POJO (Plain Old Java object to demonstrate this
comparison and sorting example in Java.
Also, in the past, I have shared Comparator example for
custom order sorting
and Comparable example for
natural order soring, if you are new to Comparator and Comparable interface in Java, you can
check those articles to get yourself familiar with Comparator and
Comparable in Java as well comparison and sorting of Java
objects.
How to compare objects using Comparator.comparing() and thenComparing() in Java
In order to demonstrate the use of Comparator and Comparable in Java 8, we
need a domain object. I like books, so I'll create a Book object with some
fields to demonstrate how you can sort a list of books using Java 8
features like
lambda expressions
and
method reference.
Here is how our Book object will be like:
public class Book implements Comparable < Book > {
private String title;
private String author;
private int price;
public Book(String title, String author, int price) {
this.title = title;
this.author = author;
this.price = price;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public int getPrice() {
return price;
}
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book [title=" + title + ", author=" + author + ", price=" +
price + "]";
}
// the old way to implement CompareTo method to compare
// object by multiple fields, you'll learn new way as well
@Override
public int compareTo(Book b) {
int i = this.title.compareTo(b.title);
if (i != 0) return i;
i = this.author.compareTo(b.author);
if (i != 0) return i;
return Integer.compare(this.price, b.price);
}
}
and here is the list of Books which we'll sort in this article:
List<Book> listOfBooks = new ArrayList<>();
listOfBooks.add(new Book("Effective Java", "Joshua Bloch", 32));
listOfBooks.add(new Book("Java Puzzlers", "Joshua Bloch", 22));
listOfBooks.add(new Book("Java Concurrency in Practice",
"Brian Goetz", 42));
listOfBooks.add(new Book("Java SE 8 for Really Impatient",
"Cay S. Horstmann", 34));
listOfBooks.add(new Book("Core Java", "Cay S. Horstmann",32));
Now, let's see how we can sort this list of objects using new features of
Java 8 and new methods added to the Comparator class like the
comparing() and
thenComparing() methods.
Let's first sort the list of books by authors again but this time using Comparator.comparing() method:
listOfBooks.sort(Comparator.comparing((Book b) -> b.getAuthor()));
Since the author is a String, this code will extract the author as key and
return a Comparator which can compare objects by author. The result will be
the same as in the preceding example as shown below:
listOfBooks.sort(Comparator.comparing((Book b) -> b.getAuthor()));
System.out.println("list of books after sorting
using comparing() method: "
+ listOfBooks);
Output:
list of books after sorting using comparing method:
[
Book [title=Java Concurrency in Practice, author=Brian Goetz, price=42],
Book [title=Java SE 8 for Really Impatient, author=Cay S. Horstmann,
price=34],
Book [title=Core Java, author=Cay S. Horstmann, price=32],
Book [title=Effective Java, author=Joshua Bloch, price=32],
Book [title=Java Puzzlers, author=Joshua Bloch, price=22]
]
Now, let's see another magic of Java 8, which will make it comparing objects
even more readable, reusable, and composable by using
method reference
instead of a
lambda expression
with
Comparator.comparing() method as
shown below:
listOfBooks.sort(Comparator.comparing(Book::getAuthor));
You can see this is much more readable, clean, and concise. You can easily
see that we are comparing books based on their author. You can also
use the thenComparing() method to
compare objects on multiple fields. For example to compare books first by
the author and then on the price you can just chain comparators as given in
the following example
listOfBooks.sort(
Comparator.comparing((Book b) -> b.getAuthor())
.thenComparing((Book b) -> b.getPrice())
Another example of comparing and thenComparing to sort objects on multiple fields
Here is another example of using Comparator. comparing() and thenComparing() methods to compare a Java object into multiple parameters. In this example, we have three comparators, the first comparator compares Student object on firstName, second compare them on both firstName and lastName, and the third comparator compares them on both name and age. For the age field, we have also used a reverse comparator which means they will be compared in reverse order.
here is a full code example:
import java.util.Comparator;
public class Student {
private String firstName;
private String lastName;
private int age;
Comparator<Student> firstNameComparator
= Comparator.comparing(Student::geFirsttName);
Comparator<Student> fullNameComparator
= Comparator.comparing(Student::geFirsttName)
.thenComparing(Student::geLastName);
Comparator<Student> nameAndAgeComparator
= Comparator.comparing(Student::geFirsttName)
.thenComparing(Student::geFirsttName)
.thenComparing(Student::getAge,
Comparator.reverseOrder());
}
You can see that we have chained comparators on the second and third examples to compare Student objects on multiple fields. You can chain as many comparators as you want, but code is still ver readable, and comparing logic is obvious. If your list contains null elements then you can also use the nullsFirst() and nullsLast() methods to put null objects either in the first or last position.
That's all about how to use
comparing() and
thenComparing() methods of the
Comparator class to compare objects in Java 8. The best thing about this
method is that you can pass lambda expression or method interface to this
method to compare objects.
If you want to learn more about advanced comparator methods like
thenComparing() then I highly recommend you to check out my post about advanced comparator and comparable examples in Java, where I have shared how to compare objects on multiple fields and
different orders in Java, including nulls.
Other Core Java Articles you may like:
- 20 Examples of Date and Time in Java 8 (tutorial)
- 5 Free Courses to learn Java 8 and 9 (courses)
- How to format/parse the date with LocalDateTime in Java 8? (tutorial)
- How to use filter() method in Java 8 (tutorial)
- How to sort the map by keys in Java 8? (example)
- How to convert List to Map in Java 8 (solution)
- What is the default method in Java 8? (example)
- 5 Books to Learn Java 8 from Scratch (books)
- How to use Stream class in Java 8 (tutorial)
- Difference between abstract class and interface in Java 8? (answer)
- How to sort the may by values in Java 8? (example)
- How to join String in Java 8 (example)
- 7 Best Collections and Stream Courses for Java developers (courses)
No comments:
Post a Comment