Java Language Trier une liste générique


Exemple

La classe Collections propose deux méthodes statiques standard pour trier une liste:

  • sort(List<T> list) applicable aux listes où T extends Comparable<? super T> , et
  • sort(List<T> list, Comparator<? super T> c) applicable aux listes de tout type.

Appliquer le premier nécessite de modifier la classe des éléments de liste en cours de tri, ce qui n'est pas toujours possible. Cela peut également être indésirable car, bien qu'il fournisse le tri par défaut, d'autres ordres de tri peuvent être requis dans différentes circonstances, ou le tri n'est qu'une tâche ponctuelle.

Considérons que nous avons pour tâche de trier les objets qui sont des instances de la classe suivante:

public class User {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }
}

Pour utiliser Collections.sort(List<User> list) nous devons modifier la classe User pour implémenter l'interface Comparable . Par exemple

public class User implements Comparable<User> {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }

    @Override
    /** The natural ordering for 'User' objects is by the 'id' field. */
    public int compareTo(User o) {
        return id.compareTo(o.id);
    }
}

(À part: de nombreuses classes Java standard telles que String , Long , Integer implémentent l'interface Comparable . Cela rend les listes de ces éléments triables par défaut et simplifie l'implémentation de compare ou compareTo dans d'autres classes.)

Avec la modification ci-dessus, nous pouvons facilement trier une liste d'objets User fonction de l' ordre naturel des classes. (Dans ce cas, nous avons défini cela comme étant basé sur les valeurs d’ id ). Par exemple:

List<User> users = Lists.newArrayList(
    new User(33L, "A"),
    new User(25L, "B"),
    new User(28L, ""));
Collections.sort(users);

System.out.print(users);
// [B:25, C:28, A:33]

Cependant, supposons que nous voulions trier User objets User par name plutôt que par id . Supposons maintenant que nous n'avions pas été en mesure de changer la classe pour le faire mettre en œuvre Comparable .

C'est là que la méthode de sort avec l'argument Comparator est utile:

Collections.sort(users, new Comparator<User>() {
    @Override
    /* Order two 'User' objects based on their names. */
    public int compare(User left, User right) {
        return left.username.compareTo(right.username);
    }
});
System.out.print(users);
// [A:33, B:25, C:28]
Java SE 8

Dans Java 8, vous pouvez utiliser un lambda au lieu d'une classe anonyme. Ce dernier se réduit à une seule ligne:

Collections.sort(users, (l, r) -> l.username.compareTo(r.username));

De plus, Java 8 ajoute une méthode de sort par défaut sur l'interface List , ce qui simplifie encore le tri.

users.sort((l, r) -> l.username.compareTo(r.username))