Java 8 Comparator

On java 8 Comparator interface there are new default methods using which compare objects in declarative way.

Say we have the Person object

public class Person {

  private String name;
  private Integer age;

  public Person(String name, Integer age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }
  
  public Integer getAge() {
    return age;
  }
  
  @Override
  public String toString() {
    return name + "-" + age;
  }
}

List people = new ArrayList<>();
people.add(new Person("Rob", 26));
people.add(new Person("Bob", 29));
people.add(new Person("Tom", 24));
people.add(new Person("Alice", 32));
people.add(new Person("Ben", 22));
people.add(new Person("Ann", 22));

Compare by name

Comparator comparator = Comparator.comparing(Person::getName);
List collect = people.stream().sorted(comparator).collect(Collectors.toList());
System.out.println(collect);

//output
[Alice-32, Ann-22, Ben-22, Bob-29, Rob-26, Tom-24]

Compare in reverse order

Comparator comparatorReverse = Comparator.comparing(Person::getName, reverseOrder());
collect = people.stream().sorted(comparatorReverse).collect(Collectors.toList());
System.out.println(collect);

//output
[Tom-24, Rob-26, Bob-29, Ben-22, Ann-22, Alice-32]

[addToAppearHere]

Compare in natural order

Comparator comparatorNatural = Comparator.comparing(Person::getName, naturalOrder());
collect = people.stream().sorted(comparatorNatural).collect(Collectors.toList());
System.out.println(collect);

If getName() returns null we can use nullsLast or nullsFirst methods to put them either in the beginning or in the end of sorted collection.

Comparator comparatorNullLast = Comparator
        .comparing(Person::getName, nullsLast(Comparator.naturalOrder()));

If we want to sort by int value we can use comparingInt method

Comparator comparatorInt = Comparator.comparingInt(Person::getAge);
collect = people.stream().sorted(comparatorInt).collect(Collectors.toList());
System.out.println(collect);

//output
[Ben-22, Ann-22, Tom-24, Rob-26, Bob-29, Alice-32]

If we want to have multiple level of comparisons we can use thenComparing method

Comparator comparatorMulti = Comparator.comparing(Person::getAge)
    .thenComparing(Person::getName);
collect = people.stream().sorted(comparatorMulti).collect(Collectors.toList());
System.out.println(collect);

//output
[Ann-22, Ben-22, Tom-24, Rob-26, Bob-29, Alice-32]