您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java中List排序的三种实现方法是怎样的
## 引言
在Java编程中,对集合进行排序是一项非常常见的操作。List作为Java集合框架中最常用的数据结构之一,提供了多种排序方式。本文将深入探讨Java中List排序的三种主要实现方法:使用`Collections.sort()`方法、使用`List.sort()`方法以及使用Java 8引入的Stream API进行排序。我们将通过详细的代码示例、性能分析和适用场景比较,帮助开发者全面掌握List排序的各种技巧。
## 一、使用Collections.sort()方法
### 1.1 基本用法
`Collections.sort()`是Java中最传统的排序方法,自Java 1.2开始就存在于集合框架中。
```java
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
Collections.sort(numbers);
System.out.println(numbers); // 输出 [1, 1, 3, 4, 5, 9]
通过Comparator接口可以实现自定义排序:
List<String> words = Arrays.asList("banana", "apple", "cherry");
Collections.sort(words, (s1, s2) -> s1.length() - s2.length());
System.out.println(words); // 输出 [apple, banana, cherry]
Collections.sort()
实际上调用的是List的sort()
方法(Java 8+),在旧版本中它使用归并排序算法,时间复杂度为O(n log n)。
Collections.sort()
不是线程安全的,在多线程环境下需要额外的同步措施:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 线程安全操作
synchronized(syncList) {
Collections.sort(syncList);
}
从Java 8开始,List接口新增了sort()
默认方法:
List<Employee> employees = getEmployees();
employees.sort(Comparator.comparing(Employee::getSalary));
default void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
优势: - 更面向对象的调用方式 - 方法链式调用更流畅 - 与Lambda表达式结合更好
products.sort(Comparator
.comparing(Product::getCategory)
.thenComparing(Product::getPrice));
Stream API提供了更声明式的排序方式:
List<String> sorted = words.stream()
.sorted()
.collect(Collectors.toList());
List<Person> sortedPeople = people.stream()
.sorted(Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName))
.collect(Collectors.toList());
对于大数据集可以使用并行流提高性能:
List<Data> largeData = getLargeData();
List<Data> sorted = largeData.parallelStream()
.sorted(customComparator)
.collect(Collectors.toList());
方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
---|---|---|---|
Collections.sort() | O(n log n) | O(n) | 通用场景 |
List.sort() | O(n log n) | O(n) | Java 8+环境 |
Stream API | O(n log n) | O(2n) | 函数式编程/大数据 |
// 传统方式
Collections.sort(list, comparator);
// 面向对象方式
list.sort(comparator);
// 函数式方式
list.stream().sorted(comparator).collect(toList());
List.sort()
Collections.sort()
Comparator
构建器// null排在前面
Comparator.nullsFirst(Comparator.naturalOrder());
// null排在后面
Comparator.nullsLast(Comparator.reverseOrder());
// 方法1
Collections.sort(list, Collections.reverseOrder());
// 方法2
list.sort(Comparator.reverseOrder());
// 方法3
list.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
Collator collator = Collator.getInstance(Locale.CHINA);
list.sort(collator);
@Getter @Setter
class Student {
private String name;
private int score;
}
List<Student> students = getStudents();
students.sort(Comparator
.comparing(Student::getScore)
.thenComparing(Student::getName));
List<Product> products = getProducts();
// 按价格升序,销量降序
products.sort(Comparator
.comparing(Product::getPrice)
.thenComparing(Product::getSales, Comparator.reverseOrder()));
Map<String, Double> gradeMap = students.stream()
.sorted(Comparator.comparing(Student::getGpa).reversed())
.limit(10)
.collect(Collectors.toMap(
Student::getName,
Student::getGpa,
(oldVal, newVal) -> oldVal,
LinkedHashMap::new
));
// 使用并行流处理百万级数据
List<BigData> result = bigDataList.parallelStream()
.sorted(Comparator.comparing(BigData::getTimestamp))
.collect(Collectors.toList());
原因:对不可变集合(如Arrays.asList()创建的)进行排序
// 错误示例
List<Integer> fixedList = Arrays.asList(5, 3, 7);
Collections.sort(fixedList); // 抛出异常
// 正确做法
List<Integer> newList = new ArrayList<>(fixedList);
Collections.sort(newList);
Java的排序算法是稳定的,即相等元素的相对位置保持不变
List.sort()
或Collections.sort()
List.sort()
Collections.sort()
// 清晰的自定义排序
inventory.sort(Comparator
.comparing(Item::getWarehouse)
.thenComparingInt(Item::getShelf)
.thenComparing(Item::getExpiryDate));
随着Java版本的更新,函数式编程风格的排序可能会更普及,但传统的List.sort()
因其简洁性仍将保持主流地位。
方法 | 描述 |
---|---|
comparing() | 创建基于函数提取的比较器 |
thenComparing() | 添加次级比较规则 |
reversed() | 反转当前比较器顺序 |
naturalOrder() | 使用自然顺序 |
nullsFirst()/nullsLast() | 处理null值的特殊比较器 |
List<Integer> largeList = new Random().ints(1_000_000).boxed().collect(Collectors.toList());
// 测试Collections.sort
long start = System.nanoTime();
Collections.sort(largeList);
long duration = (System.nanoTime() - start) / 1_000_000;
System.out.println("Collections.sort: " + duration + "ms");
”`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。