排序通用列表
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 類,如 String
,Long
,Integer
實現了 Comparable
介面。這使得這些元素的列表預設可排序,並簡化了 compare
或 compareTo
在其他類中的實現。)
通過上面的修改,我們可以根據類自然排序輕鬆地對 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
而不是 id
對 User
物件進行排序。或者,假設我們無法更改類以使其實現 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))