排序
JDK版本:<font color="red">17</font>
定义一个Book类,方便举例使用
static class Book {
private String name;
private BigDecimal price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price.setScale(SCALE_NUM, ROUNDING_MODE);
}
public void setPrice(String price) {
this.price = new BigDecimal(price).setScale(SCALE_NUM, ROUNDING_MODE);
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
1. 基本排序方法
最基本的排序是使用java.util.Comparator
接口。
List<Book> books = new ArrayList<>();
// 按照价格升序
books.sort(new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o1.price.compareTo(o2.price);
}
});
// 按照价格降序
books.sort(new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o2.price.compareTo(o1.price);
}
});
2. 加入Lambda
// 按照价格升序
books.sort((o1, o2) -> o1.getPrice().compareTo(o2.getPrice()));
// 按照价格降序
Comparator<Book> comparator = (o1, o2) -> o1.getPrice().compareTo(o2.getPrice());
books.sort(comparator.reversed());
// 多个字段排序
// 更简洁的写法 可以直接调用对象的方法进行使用
Comparator<Book> comparator = Comparator.comparing(Book::getPrice).thenComparing(Book::getName);
books.sort(comparator);
3. 静态方法
class Book {
public static int compareByNameThenPrice(Book o1, Book o2) {
return o1.price.compareTo(o2.price);
}
}
// 按照价格升序
books.sort(Book::compareByNameThenPrice);
4. Collections.sort方法
// 按照价格降序
Collections.sort(books, Comparator.comparing(Book::getPrice).reversed());
5. 逆序
Comparator<Book> c1 = Comparator.comparing(Book::getPrice);
books.sort(c1.reversed());
// 或者
Comparator<Book> c1 = Comparator.comparing(Book::getPrice).reversed();
books.sort(c1);
6. Stream.sorted方法
// 按照价格升序
List<Book> newBooks = books.stream().sorted(Comparator.comparing(Book::getPrice)).toList();
// 默认自然顺序
List<String> letters = Lists.newArrayList("B", "A", "C");
List<String> sortedLetters = letters.stream().sorted().toList();
assertThat(sortedLetters.get(0), equalTo("A"));
处理空值
到目前为止,我们以无法对包含空值的集合进行排序的方式实现我们的比较器。也就是说,如果集合包含至少一个 null 元素,则排序方法会抛出 NullPointerException:
books.add(null);
Collections.sort(books, Comparator.comparing(Book::getPrice).reversed());
最简单的解决方案是在我们的比较器实现中手动处理空值:
books.add(null);
Comparator<Book> comparator = (o1, o2) -> {
if (o1 == null) {
return o2 == null ? 0 : 1;
} else if (o2 == null) {
return -1;
}
return o1.price.compareTo(o2.price);
};
books.sort(comparator);
在这里,我们将所有 null 元素推向集合的末尾。为此,比较器认为空值大于非空值。当两者都为空时,它们被认为是相等的。
使用nullsLast或者nullsFirst:
books.add(null);
books.sort(Comparator.nullsLast(Comparator.comparing(Book::getPrice)));
网友评论