排序通用列表

Collections 類提供了兩種標準靜態方法來對列表進行排序:

  • sort(List<T> list) 適用於 T extends Comparable<? super T>
  • sort(List<T> list, Comparator<? super T> c) 適用於任何型別的列表。

應用前者需要修改被排序的列表元素的類,這並不總是可行的。它也可能是不合需要的,因為雖然它提供預設排序,但在不同情況下可能需要其他排序順序,或者排序只是一次性任務。

考慮我們有一個排序物件的任務,這些物件是以下類的例項:

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

為了使用 Collections.sort(List<User> list),我們需要修改 User 類來實現 Comparable 介面。例如

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

(旁白:許多標準的 Java 類,如 StringLongInteger 實現了 Comparable 介面。這使得這些元素的列表預設可排序,並簡化了 comparecompareTo 在其他類中的實現。)

通過上面的修改,我們可以根據類自然排序輕鬆地對 User 物件列表進行排序。 (在這種情況下,我們已經定義了基於 id 值的排序)。例如:

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]

但是,假設我們想要通過 name 而不是 idUser 物件進行排序。或者,假設我們無法更改類以使其實現 Comparable

這是使用 Comparator 引數的 sort 方法有用的地方:

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]

Version >= Java SE 8

在 Java 8 中,你可以使用 lambda 而不是匿名類。後者減少為單線:

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

此外,Java 8 在 List 介面上新增了預設的 sort 方法,這進一步簡化了排序。

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