Java Language Ordinamento di un elenco generico


Esempio

La classe Collections offre due metodi statici standard per ordinare un elenco:

  • sort(List<T> list) applicabile agli elenchi in cui T extends Comparable<? super T> , e
  • sort(List<T> list, Comparator<? super T> c) applicabile a liste di qualsiasi tipo.

L'applicazione del primo richiede la modifica della classe di elementi di elenco ordinati, il che non è sempre possibile. Potrebbe anche non essere desiderabile poiché, sebbene fornisca l'ordinamento predefinito, altri ordini di ordinamento potrebbero essere richiesti in circostanze diverse, o l'ordinamento è solo un'attività a parte.

Considera che abbiamo un'attività di ordinare oggetti che sono istanze della seguente classe:

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

Per utilizzare Collections.sort(List<User> list) è necessario modificare la classe User per implementare l'interfaccia Comparable . Per esempio

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

(A parte: molte classi Java standard come String , Long , Integer implementano l'interfaccia Comparable rende gli elenchi di quegli elementi ordinabili per impostazione predefinita e semplifica l'implementazione di compare o compareTo in altre classi.)

Con la modifica sopra, possiamo facilmente ordinare un elenco di oggetti User base all'ordine naturale delle classi. (In questo caso, abbiamo definito che essere ordinati in base ai valori id ). Per esempio:

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]

Tuttavia, supponiamo di voler ordinare gli oggetti User per name anziché per id . In alternativa, supponiamo di non essere stato in grado di modificare la classe per renderla Comparable .

È qui che il metodo di sort con l'argomento Comparator è 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

In Java 8 puoi usare una lambda invece di una classe anonima. Quest'ultimo si riduce ad un unico rivestimento:

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

Inoltre, Java 8 aggiunge un metodo di sort predefinito all'interfaccia List , che semplifica ulteriormente l'ordinamento.

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