Java - Comparing Objects using Comparator functional interface

Introduction

The Comparator interface is a functional interface with the following declaration:

package java.util;

@FunctionalInterface
public interface Comparator<T> {
        int compare(T o1, T o2);
        ...
}

Comparator interface contains many default and static methods that can be used along with lambda expressions to create its instances.

The following two methods of the Comparator interface:

static <T,U extends Comparable<? super U>>Comparator<T> 
        comparing(Function<? super T,? extends U> keyExtractor)
default <U extends Comparable<? super U>>Comparator<T> 
        thenComparing(Function<? super T,? extends U> keyExtractor)

comparing() method takes a Function and returns a Comparator.

It should return a Comparable that is used to compare two objects.

You can create a Comparator object to compare Person objects based on their first name, as shown:

Comparator<Person> firstNameComp = Comparator.comparing(Person::getFirstName);

thenComparing() method is a default method which is used to specify a secondary comparison if two objects are the same in sorting order based on the primary comparison.

The following code creates a Comparator<Person> that sorts Person objects based on their last names, first names, and DOBs:

Comparator<Person> lastFirstDobComp =
       Comparator.comparing(Person::getLastName)
                 .thenComparing(Person::getFirstName)
                 .thenComparing(Person::getDob);

The following code shows how to use the method references to create a Comparator objects to sort Person objects.

It uses the sort() default method of the List interface to sort the list of persons.

The sort() method takes a Comparator as an argument.

Demo

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

public class Main {
  public static void main(String[] args) {
    List<Person> persons = Person.getPersons();

    // Sort using the first name
    persons.sort(Comparator.comparing(Person::getFirstName));

    // Print the sorted list
    System.out.println("Sorted by the first name:");
    forEach(persons, System.out::println);

    // Sort using the last name, first name, and then DOB
    persons.sort(/*  w w w .  j a  v  a  2  s .c o m*/
        Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName).thenComparing(Person::getDob));

    // Print the sorted list
    System.out.println("\nSorted by the last name, first name, and dob:");
    forEach(persons, System.out::println);
  }
  // Applies an action on each item in a list
  public static <T> void forEach(List<T> list, Consumer<? super T> action) {
    for (T item : list) {
      action.accept(item);
    }
  }
}

enum Gender {
  MALE, FEMALE
}

class Person {
  private String firstName;
  private String lastName;
  private LocalDate dob;
  private Gender gender;

  public Person(String firstName, String lastName, LocalDate dob, Gender gender) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.dob = dob;
    this.gender = gender;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public LocalDate getDob() {
    return dob;
  }

  public void setDob(LocalDate dob) {
    this.dob = dob;
  }

  public Gender getGender() {
    return gender;
  }

  public void setGender(Gender gender) {
    this.gender = gender;
  }

  @Override
  public String toString() {
    return firstName + " " + lastName + ", " + gender + ", " + dob;
  }

  // A utility method
  public static List<Person> getPersons() {
    ArrayList<Person> list = new ArrayList<>();
    list.add(new Person("A", "D", LocalDate.of(1975, 1, 20), Gender.MALE));
    list.add(new Person("B", "E", LocalDate.of(1965, 9, 12), Gender.MALE));
    list.add(new Person("C", "D", LocalDate.of(1970, 9, 12), Gender.FEMALE));
    return list;
  }
}

Result

Related Example