- 排序一维列表(如整数列表)
import java.util.Arrays; import java.util.Collections; // 假设有一个整数列表 List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9); // 使用Lambda表达式进行升序排序 Collections.sort(numbers, (a, b) -> a - b); // 使用Lambda表达式进行降序排序 Collections.sort(numbers, (a, b) -> b - a);
- 排序二维数组列表(如每个数组包含两个元素的列表)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
// 假设有一个二维数组列表,每个数组包含两个元素
List<int[]> pairs = new ArrayList<>();
pairs.add(new int[]{1, 3});
pairs.add(new int[]{2, 2});
pairs.add(new int[]{1, 2});
// 按照第一个元素升序排序
Collections.sort(pairs, (a, b) -> a[0] - b[0]);
// 按照第二个元素降序排序
Collections.sort(pairs, (a, b) -> b[1] - a[1]);
- 排序三维数组列表(如每个数组包含三个元素的列表)
// 假设有一个三维数组列表,每个数组包含三个元素
List<int[]> triples = new ArrayList<>();
triples.add(new int[]{1, 3, 5});
triples.add(new int[]{2, 2, 4});
triples.add(new int[]{1, 2, 3});
// 按照第一个元素升序排序
Collections.sort(triples, (a, b) -> a[0] - b[0]);
// 按照第二个元素升序排序,如果第一个元素相同,则按照第三个元素降序排序
Collections.sort(triples, (a, b) -> {
if (a[0] != b[0]) {
return a[0] - b[0];
} else {
return b[2] - a[2];
}
});
注意事项:
- Lambda表达式
(a, b) -> a - b用于升序排序,(a, b) -> b - a用于降序排序。 - 对于多维数组列表,可以根据需要比较数组中的不同元素来决定排序顺序。
- 如果需要更复杂的排序逻辑,可以在Lambda表达式中使用更复杂的代码块,如上面的三维数组列表示例所示。
- 根据二维数组间的差值来排序列表
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 假设有一个二维数组列表,每个数组包含两个元素:资本需求和利润
List<int[]> projects = new ArrayList<>();
projects.add(new int[]{10, 5}); // 项目1,资本需求10,利润5
projects.add(new int[]{7, 3}); // 项目2,资本需求7,利润3
projects.add(new int[]{4, 2}); // 项目3,资本需求4,利润2
// 根据每个数组中利润减去资本需求的差值进行升序排序
Collections.sort(projects, (a, b) -> (a[1] - a[0]) - (b[1] - b[0]));
// 降序
// Collections.sort(projects, (a, b) -> (b[1] - b[0]) - (a[1] - a[0]));
// 打印排序后的列表
for (int[] project : projects) {
System.out.println(Arrays.toString(project));
}
}
}
- PriorityQueue 堆
- PriorityQueue 简介
- PriorityQueue 是 Java 中的一个类,实现了 Queue 接口,用于存储一组元素,并按照优先级顺序排列这些元素。
- 它不是一个线程安全的队列,如果多个线程需要访问同一个 PriorityQueue 实例,那么必须使用外部同步。
- 创建 PriorityQueue
- 可以通过其构造函数创建一个空的 PriorityQueue。
- 可以传递一个 Comparator 来定义元素的排序规则。
- Lambda 表达式在 PriorityQueue 中的应用
- 常用方法
add(E e)或offer(E e): 将元素插入到队列中。poll(): 移除并返回队列头部的元素,如果队列为空,则返回 null。peek(): 返回队列头部的元素,但不移除它,如果队列为空,则返回 null。
- 示例代码
- PriorityQueue 简介
// 创建一个最大堆的 PriorityQueue PriorityQueue<Integer> maxHeap new PriorityQueue<>((a, b) -> b - a); // 添加元素 maxHeap.add(10); maxHeap.add(5); maxHeap.add(20); // 获取并移除最大元素 System.out.println(maxHeap.poll()); // 输出 20// 查看队列头部元素 System.out.println(maxHeap.peek()); // 输出 10
- 注意事项
- PriorityQueue 不允许 null 元素。
- PriorityQueue 的元素必须能够进行比较,即实现了 Comparable 接口,或者在创建 PriorityQueue 时提供了 Comparator。
- Lambda表达式在其他排序场景的应用
- 数组排序
Lambda表达式可以用于数组的排序,允许你自定义排序规则。
Integer[] numbers = {3, 1, 4, 1, 5, 9};
Arrays.sort(numbers, (a, b) -> b - a); // 降序排序
- 集合排序
可以对任何集合(如 List)进行排序,使用 Lambda 表达式定义排序逻辑。
List<String> words = Arrays.asList("banana", "apple", "cherry");
words.sort((a, b) -> a.length() - b.length()); // 按字符串长度升序排序
- Stream 排序
在 Java 8 的 Stream API 中,Lambda 表达式常用于排序操作。
List<Person> people = ...;
people.stream()
.sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
.forEach(System.out::println); // 按名字排序并打印
- 自定义对象排序
Lambda 表达式可以用于自定义对象的排序,根据对象的某个属性或复杂逻辑。
List<Person> people = ...; people.sort((p1, p2) -> p1.getAge() - p2.getAge()); // 按年龄升序排序
- 并行排序
在并行处理数据时,Lambda 表达式可用于并行排序。
Arrays.parallelSort(numbers, (a, b) -> b - a); // 并行降序排序
- 多条件排序
Lambda 表达式可以用于实现多条件排序。
List<Person> people = ...;
people.sort((p1, p2) -> {int nameCompare = p1.getName().compareTo(p2.getName());if (nameCompare != 0) return nameCompare;return p1.getAge() - p2.getAge(); // 如果名字相同,则按年龄排序
});
- 在数据库查询中使用
在某些框架中,如 JPA 或 Hibernate,Lambda 表达式可以用于定义查询结果的排序。
List<Person> people = repository.findAll(Sort.by(Sort.Order.asc(p -> p.getName())));
Lambda 表达式在排序中的应用非常灵活,可以根据具体的业务逻辑来定义排序规则,使得代码更加简洁和直观。它们在处理集合、数组、流等数据结构时提供了强大的排序能力。
- Lambda表达式的其他应用场景
Lambda表达式是Java 8中引入的一个非常重要的特性,它使得Java支持函数式编程。
以下是Lambda表达式的一些常见应用场景:
- 简化代码
- 匿名内部类简写:Lambda表达式可以替代传统的匿名内部类,使代码更加简洁。
- 事件处理:在GUI编程中,Lambda表达式可以用来处理事件监听。
- 集合操作
- 遍历集合:使用
forEach方法可以方便地遍历集合。 - 过滤集合:使用
filter方法可以根据条件筛选集合中的元素。 - 映射操作:使用
map方法可以将集合中的元素转换成另一种形式。
- 遍历集合:使用
- 函数式接口
- 自定义函数式接口:可以创建自定义的函数式接口,然后用Lambda表达式实现它们。
- 并发编程
- 线程创建:Lambda表达式可以简化线程的创建。
- 异步操作:在
CompletableFuture中使用Lambda表达式处理异步任务。
- Stream API
- 复杂的数据处理:利用Stream API进行数据转换、聚合等操作。
- 方法引用
- 方法引用简写:Lambda表达式可以与方法引用结合使用,进一步简化代码。
- 设计模式
- 策略模式:Lambda表达式可以用来实现策略模式,使得策略的实现更加灵活。
- 模板方法模式:使用Lambda表达式作为模板方法中的钩子。
- 资源管理
- try-with-resources:Java 9引入了可以使用Lambda表达式的try-with-resources语法。
try (var resource = getResource()) {// use resource
}
- 事件处理和回调
- 事件监听器:在Swing或JavaFX等框架中,Lambda表达式可以用来处理事件。
- 回调函数:在异步操作完成时执行Lambda表达式定义的回调逻辑。
Lambda表达式的引入极大地丰富了Java编程语言的表达能力,使得代码更加简洁、灵活,并且易于理解和维护。