回答
Java 对 List 集合有如下几种排序方式:
- 使用
Collections.sort()
:该方法提供了两种排序方式,一种是自然排序,一种是使用 Comparator 比较器进行排序。 - 使用
List.sort()
:Java 8,在 List 接口中提供了sort(Comparator<? super E> c)
,允许我们直接对列表排序。 - 使用Stream API:利用 Stream 的
sorted()
可以对 List 中的元素进行排序。
详解
使用 Collections.sort()
Collections.sort()
有两个重载的方法。
- 自然排序
public static <T extends Comparable<? super T>> void sort(List<T> list)
该方法对列表中的元素按照它们的自然顺序进行排序,它要求列表中的元素实现了 Comparable
接口,并且相互之间可以进行比较。
@Data
@AllArgsConstructor
public class Student implements Comparable<Student> {
private String name;
private Integer age;
@Override
public int compareTo(Student student) {
int flag = this.age.compareTo(student.getAge());
if (flag == 0) {
flag = this.name.compareTo(student.getName());
}
return flag;
}
}
@Test
public void listSortTest() {
List<Student> students = new ArrayList<>();
students.add(new Student("张三",13));
students.add(new Student("李四",12));
students.add(new Student("王五",15));
students.add(new Student("赵六",14));
students.add(new Student("刘七",13));
Collections.sort(students);
System.out.println(students);
}
执行结果:
[Student(name=李四, age=12), Student(name=刘七, age=13), Student(name=张三, age=13), Student(name=赵六, age=14), Student(name=王五, age=15)]
注意,使用这种方式,List 中的元素一定要实现 Comparable 接口,否则会抛出 ClassCastException
异常。
- 定制排序
public static <T> void sort(List<T> list, Comparator<? super T> c)
根据指定的比较器对 List 进行排序。如果提供的比较器为null
,则列表中的元素将按照自然顺序排序。还是上的例子,这次我们按照 name 属性排序:
@Test
public void listSortTest() {
//...
Collections.sort(students, Comparator.comparing(Student::getName));
System.out.println(students);
}
执行结果:
[Student(name=刘七, age=13), Student(name=张三, age=13), Student(name=李四, age=12), Student(name=王五, age=15), Student(name=赵六, age=14)]
使用 List.sort()
Java 8 增加了一个默认方法 sort(Comparator<? super E> comparator)
,该方法允许直接在列表上进行排序操作,而无需使用Collections.sort()
。这种方式比 Collections.sort()
更加简洁。
方法接受一个Comparator
对象作为参数,用于比较列表中的元素。如果传入的Comparator
是null
,那么列表中的元素将按照它们的自然顺序进行排序,这就要求元素实现Comparable
接口,否则会抛出 ClassCastException
异常。
@Test
public void listSortTest() {
//...
students.sort(Comparator.comparing(Student::getAge));
System.out.println(students);
}
执行结果:
[Student(name=李四, age=12), Student(name=张三, age=13), Student(name=刘七, age=13), Student(name=赵六, age=14), Student(name=王五, age=15)]
使用Stream API
使用 Stream API 对 List 进行排序是一种更加方便的方式。如下:
@Test
public void listSortTest() {
//...
students.stream().sorted().forEach(System.out::println);
}
执行结果:
Student(name=李四, age=12)
Student(name=刘七, age=13)
Student(name=张三, age=13)
Student(name=赵六, age=14)
Student(name=王五, age=15)
这是一种自然排序的方式,也可以指定比较器:
@Test
public void listSortTest() {
//...
students.stream().sorted(Comparator.comparing(Student::getName)).forEach(System.out::println);
}
执行结果:
Student(name=刘七, age=13)
Student(name=张三, age=13)
Student(name=李四, age=12)
Student(name=王五, age=15)
Student(name=赵六, age=14)
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。