简介
Java 流 API 提供了一种强大且灵活的方式来处理数据集合。在本教程中,我们将探讨如何使用流 API 对集合执行常见操作和转换,使你能够编写更简洁、易读且高效的 Java 代码。
Java 流 API 提供了一种强大且灵活的方式来处理数据集合。在本教程中,我们将探讨如何使用流 API 对集合执行常见操作和转换,使你能够编写更简洁、易读且高效的 Java 代码。
Java 流 API 是 Java 8 中引入的一项强大功能,它允许你以更声明式和函数式的风格处理数据集合。流提供了一种对集合执行各种操作的方式,例如过滤、映射、排序和归约,而无需显式迭代或可变状态。
Java 流是一系列元素,支持以类似管道的方式执行各种操作。流本身不是数据结构,而是在现有数据结构(如集合、数组或 I/O 资源)之上进行操作。
流为处理集合提供了高级抽象,使你能够专注于做什么(期望的结果)而不是如何做(实现细节)。
典型的流管道由三个主要部分组成:
以下是一个对流中的数字进行过滤、映射和归约的流管道示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.reduce(0, Integer::sum);
System.out.println("Sum of even numbers doubled: " + sum); // 输出:110
在下一节中,我们将更深入地探讨可用于处理数据的常见流操作和转换。
Java 流提供了各种各样的操作和转换,可用于处理你的数据。让我们来探讨一些最常见的操作:
filter()
操作允许你根据给定的谓词从流中选择元素。例如,要从列表中过滤出偶数:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // 输出:[2, 4, 6, 8, 10]
map()
操作允许你使用提供的函数转换流中的每个元素。例如,要将列表中每个数字的值翻倍:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubledNumbers = numbers.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println(doubledNumbers); // 输出:[2, 4, 6, 8, 10]
sorted()
操作允许你根据元素的自然顺序或自定义比较器对流中的元素进行排序。例如,要按字母逆序对字符串列表进行排序:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> sortedNames = names.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
System.out.println(sortedNames); // 输出:[David, Charlie, Bob, Alice]
reduce()
操作允许你将流中的元素组合成单个值。例如,要计算数字列表的总和:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println(sum); // 输出:15
collect()
操作允许你将流管道的结果收集到新的数据结构中,如 List
、Set
或 Map
。例如,要收集字符串列表的唯一长度:
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
Set<Integer> uniqueLengths = words.stream()
.map(String::length)
.collect(Collectors.toSet());
System.out.println(uniqueLengths); // 输出:[5, 6, 4]
这些只是 Java 流 API 中众多操作和转换的几个示例。在下一节中,我们将探讨一些使用流的实际示例和用例。
既然我们已经介绍了 Java 流 API 的基础知识,那就来探讨一些实际的示例和用例。
假设你有一个 Person
对象列表,你想找出所有成年人(年龄 18 岁及以上),并创建一个新的列表,其中包含他们名字的大写形式:
class Person {
private String name;
private int age;
// 构造函数、getter 和 setter
}
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 17),
new Person("Charlie", 32),
new Person("David", 14)
);
List<String> adultNames = people.stream()
.filter(p -> p.getAge() >= 18)
.map(Person::getName)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(adultNames); // 输出:[ALICE, CHARLIE]
假设你有一个产品列表,你想按类别对它们进行分组,并计算每个类别的总价:
class Product {
private String name;
private String category;
private double price;
// 构造函数、getter 和 setter
}
List<Product> products = Arrays.asList(
new Product("Apple", "Fruit", 0.5),
new Product("Banana", "Fruit", 0.25),
new Product("Carrot", "Vegetable", 0.3),
new Product("Broccoli", "Vegetable", 0.4)
);
Map<String, Double> totalPriceByCategory = products.stream()
.collect(Collectors.groupingBy(
Product::getCategory,
Collectors.summingDouble(Product::getPrice)
));
System.out.println(totalPriceByCategory); // 输出:{Fruit=0.75, Vegetable=0.7}
流可以很容易地并行化,以利用多核处理器并提高对大型数据集的处理性能。以下是一个如何使用并行流来计算前 100 万个整数之和的示例:
long sum = LongStream.rangeClosed(1, 1_000_000)
.parallel()
.sum();
System.out.println(sum); // 输出:500000500000
通过使用 parallel()
方法,流操作会分布在多个线程上,从而使计算能够更高效地执行。
这些只是 Java 流 API 众多实际用例中的几个示例。流的强大之处在于它们能够以简洁且易读的方式表达复杂的数据处理管道,同时还提供了优化性能和可扩展性的灵活性。
在本教程结束时,你将对 Java 流 API 有扎实的理解,以及如何应用它来有效地处理集合。你将学习常见的流操作、实际示例和实际应用场景,从而提升你的 Java 编程技能,并编写更具表现力、函数式和高性能的代码。