Java Language Utilisation des expressions lambda pour trier une collection


Exemple

Tri des listes

Avant Java 8, il était nécessaire d'implémenter l'interface java.util.Comparator avec une classe anonyme (ou nommée) lors du tri d'une liste 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());
        }
    }
);

À partir de Java 8, la classe anonyme peut être remplacée par une expression lambda. Notez que les types pour les paramètres p1 et p2 peuvent être omis, comme le compilateur les inférera automatiquement:

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

L'exemple peut être simplifié en utilisant Comparator.comparing et les références de méthode exprimées en utilisant le symbole :: (deux points).

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

Une importation statique nous permet de l'exprimer de manière plus concise, mais on peut se demander si cela améliore la lisibilité globale:

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

Les comparateurs construits de cette manière peuvent également être enchaînés. Par exemple, après avoir comparé des personnes par leur prénom, s'il y a des personnes avec le même prénom, la méthode thenComparing avec également comparer par nom de famille:

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

1 - Notez que Collections.sort (...) ne fonctionne que sur les collections qui sont des sous-types de List . Les API Set et Collection n'impliquent aucun classement des éléments.

Tri des cartes

Vous pouvez trier les entrées d'un HashMap par valeur de la même manière. (Notez qu'un LinkedHashMap doit être utilisé comme cible. Les clés d'un HashMap ordinaire HashMap sont pas ordonnées.)

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));