Java Stream API
Java Stream API 是 Java 8 引入的一个强大的工具,用于处理集合数据。它提供了一种声明式的方式来操作数据流,使得代码更加简洁、易读,并且可以利用多核架构进行并行处理。Stream API 的核心思想是将数据看作一个流,通过一系列的操作(如过滤、映射、排序等)来处理数据。
什么是 Stream?
Stream 是数据源的抽象,它可以是一个集合、数组、I/O 通道等。Stream 本身并不存储数据,而是对数据源进行操作。Stream 操作分为两类:
- 中间操作(Intermediate Operations):返回一个新的 Stream,允许链式调用。例如:
filter
、map
、sorted
等。 - 终端操作(Terminal Operations):触发 Stream 的处理并返回结果或副作用。例如:
forEach
、collect
、reduce
等。
Stream 操作是惰性的,只有在终端操作被调用时,中间操作才会真正执行。
创建 Stream
在 Java 中,可以通过多种方式创建 Stream:
- 从集合创建:使用
stream()
或parallelStream()
方法。 - 从数组创建:使用
Arrays.stream()
方法。 - 使用 Stream.of():直接创建 Stream。
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
// 从集合创建 Stream
List<String> list = Arrays.asList("Java", "Python", "C++");
Stream<String> stream1 = list.stream();
// 从数组创建 Stream
String[] array = {"Java", "Python", "C++"};
Stream<String> stream2 = Arrays.stream(array);
// 使用 Stream.of() 创建 Stream
Stream<String> stream3 = Stream.of("Java", "Python", "C++");
}
}
常用 Stream 操作
1. 过滤(Filter)
filter
方法用于过滤 Stream 中的元素,只保留满足条件的元素。
java
List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript");
List<String> filteredLanguages = languages.stream()
.filter(language -> language.startsWith("J"))
.collect(Collectors.toList());
System.out.println(filteredLanguages); // 输出: [Java, JavaScript]
2. 映射(Map)
map
方法用于将 Stream 中的每个元素映射为另一个元素。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
List<Integer> languageLengths = languages.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(languageLengths); // 输出: [4, 6, 3]
3. 排序(Sorted)
sorted
方法用于对 Stream 中的元素进行排序。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
List<String> sortedLanguages = languages.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedLanguages); // 输出: [C++, Java, Python]
4. 聚合(Reduce)
reduce
方法用于将 Stream 中的元素聚合为一个结果。
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println(sum); // 输出: 15
实际应用场景
案例 1:统计单词频率
假设我们有一个文本文件,需要统计每个单词出现的频率。
java
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class WordFrequency {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "apple", "orange", "banana", "apple");
Map<String, Long> wordFrequency = words.stream()
.collect(Collectors.groupingBy(word -> word, Collectors.counting()));
System.out.println(wordFrequency); // 输出: {orange=1, banana=2, apple=3}
}
}
案例 2:并行处理大数据集
Stream API 支持并行处理,可以充分利用多核 CPU 的优势。
java
import java.util.Arrays;
import java.util.List;
public class ParallelStreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
System.out.println(sum); // 输出: 55
}
}
总结
Java Stream API 提供了一种高效、简洁的方式来处理集合数据。通过使用 Stream,我们可以轻松地实现过滤、映射、排序、聚合等操作,并且可以利用并行流来提高处理速度。Stream API 的声明式编程风格使得代码更加易读和易于维护。
提示
提示:在使用 Stream API 时,尽量避免在中间操作中修改外部状态,以保持代码的纯净性和可维护性。
附加资源与练习
- 官方文档:阅读 Java Stream API 官方文档 以了解更多细节。
- 练习:尝试使用 Stream API 实现以下功能:
- 从一个整数列表中找出所有偶数并求和。
- 从一个字符串列表中找出长度大于 5 的字符串,并将其转换为大写。
通过不断练习,你将更加熟练地掌握 Java Stream API 的使用。