Java Language Usando expresiones Lambda para ordenar una colección


Ejemplo

Listas de clasificación

Antes de Java 8, era necesario implementar la interfaz java.util.Comparator con una clase anónima (o nombrada) al ordenar una lista 1 :

Java SE 1.2
List<Person> people = ...
Collections.sort(
    people,
    new Comparator<Person>() {
        public int compare(Person p1, Person p2){
            return p1.getFirstName().compareTo(p2.getFirstName());
        }
    }
);

A partir de Java 8, la clase anónima se puede reemplazar con una expresión lambda. Tenga en cuenta que los tipos para los parámetros p1 y p2 se pueden omitir, ya que el compilador los deducirá automáticamente:

Collections.sort(
    people, 
    (p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName())
);

El ejemplo se puede simplificar utilizando Comparator.comparing y referencias de métodos expresadas con el símbolo :: (dos puntos).

Collections.sort(
    people,
    Comparator.comparing(Person::getFirstName)
);

Una importación estática nos permite expresar esto de manera más concisa, pero es discutible si esto mejora la legibilidad general:

import static java.util.Collections.sort;
import static java.util.Comparator.comparing;
//...
sort(people, comparing(Person::getFirstName));

Los comparadores construidos de esta manera también se pueden encadenar juntos. Por ejemplo, después de comparar personas por su primer nombre, si hay personas con el mismo nombre, el método thenComparing también se compara por apellido:

sort(people, comparing(Person::getFirstName).thenComparing(Person::getLastName));

1: tenga en cuenta que Collections.sort (...) solo funciona en colecciones que son subtipos de List . Las API de Set y Collection no implican ningún orden de los elementos.

Clasificando mapas

Puede ordenar las entradas de un HashMap por valor de una manera similar. (Tenga en cuenta que debe utilizarse un LinkedHashMap como destino. Las claves en un HashMap normal no están ordenadas).

Map<String, Integer> map = new HashMap();  // ... or any other Map class
// populate the map
map = map.entrySet()
    .stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue())
    .collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue(),
                              (k, v) -> k, LinkedHashMap::new));