Lambda and Sorting for Java8

  • 2021-12-11 07:24:42
  • OfStack

Directory

Sorting arrays and collections is Java 8 lambda Amazing 1 application, we can implement 1 Comparators To implement various sorts.

Look at the following case:


static class Person {

    final String firstName;

    final String lastName;

 
  
    Person(String firstName, String lastName) {

        this.firstName = firstName;

        this.lastName = lastName;

    }

 

    @Override

    public String toString() {

        return "Person{" +

                "firstName='" + firstName + '\'' +

                ", lastName='" + lastName + '\'' +

                '}';

    }

}

The data for Person are:


List<Person> people =

Arrays.asList(

    new Person("Jane", "Henderson"),

    new Person("Michael", "White"),

    new Person("Henry", "Brighton"),

    new Person("Hannah", "Plowman"),

    new Person("William", "Henderson")

);

We want to sort by name ( last name ), and then according to the last name ( first name ).

Before Java 7, we usually implemented an Comparator:


people.sort(new Comparator<Person>() {

  @Override

  public int compare(Person o1, Person o2) {

    int result = o1.lastName.compareTo(o2.lastName);

 

    if (result == 0)

      result = o1.firstName.compareTo(o2.firstName);

 

    return result;

  }

});

people.forEach(System.out::println);

In Java 8, we can use lambda instead of anonymous functions, as follows:


Comparator<Person> c = (p, o) -> p.lastName.compareTo(o.lastName);

 

c = c.thenComparing((p, o) -> p.firstName.compareTo(o.firstName));

 

people.sort(c);

people.forEach(System.out::println);

Here, Lambda Expression (p, o) -> p.lastName.compareTo(o.lastName) Replace the previous anonymous function new Comparator<Person>() {}

Because Java The compiler can't delay the Lambda Expression type judgment, such as delaying until the comparator Pass to Comparators0 Method, so we make the chain Comparator It's a little difficult to write,

For example, we want to write as follows:


 
XXX.thenComparing((p, o) -> p.lastName.compareTo(o.lastName))
       .thenComparing((p, o) -> p.firstName.compareTo(o.firstName))

In other words, type determination is left-to-right, not right-to-left, and we can do type inference by creating a generic type:


class Utils {

    static <E> Comparator<E> compare() {

        return (e1, e2) -> 0;

    }

}

With the compare () method above, we can write a smooth comparator chain:


people.sort(

    Utils.<Person>compare()

         .thenComparing((p, o) ->

              p.lastName.compareTo(o.lastName))

         .thenComparing((p, o) ->

              p.firstName.compareTo(o.firstName))

);

 

people.forEach(System.out::println);

Related articles: