Java Stream API #
一、Stream概述 #
1.1 什么是Stream #
Stream是Java 8引入的用于处理集合的API,支持函数式编程风格。
1.2 Stream特点 #
- 声明式编程
- 链式操作
- 惰性求值
- 可并行处理
1.3 Stream vs Collection #
| 特性 | Stream | Collection |
|---|---|---|
| 存储 | 不存储数据 | 存储数据 |
| 操作 | 惰性求值 | 立即执行 |
| 消费 | 只能消费一次 | 可多次遍历 |
二、创建Stream #
2.1 从集合创建 #
java
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream1 = list.stream();
Stream<String> stream2 = list.parallelStream(); // 并行流
2.2 从数组创建 #
java
String[] array = {"A", "B", "C"};
Stream<String> stream1 = Arrays.stream(array);
Stream<String> stream2 = Stream.of("A", "B", "C");
2.3 创建无限流 #
java
// iterate
Stream<Integer> iterate = Stream.iterate(0, n -> n + 2);
iterate.limit(10).forEach(System.out::println);
// generate
Stream<Double> generate = Stream.generate(Math::random);
generate.limit(5).forEach(System.out::println);
2.4 创建空流 #
java
Stream<String> empty = Stream.empty();
三、中间操作 #
3.1 filter过滤 #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evens = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// [2, 4, 6, 8, 10]
3.2 map映射 #
java
List<String> names = Arrays.asList("alice", "bob", "charlie");
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// [ALICE, BOB, CHARLIE]
// flatMap扁平化
List<List<Integer>> nested = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4)
);
List<Integer> flat = nested.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
// [1, 2, 3, 4]
3.3 sorted排序 #
java
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
List<Integer> sorted = numbers.stream()
.sorted()
.collect(Collectors.toList());
// [1, 1, 3, 4, 5, 9]
List<Integer> descSorted = numbers.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
// [9, 5, 4, 3, 1, 1]
3.4 distinct去重 #
java
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> distinct = numbers.stream()
.distinct()
.collect(Collectors.toList());
// [1, 2, 3]
3.5 limit和skip #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> limited = numbers.stream()
.limit(5)
.collect(Collectors.toList());
// [1, 2, 3, 4, 5]
List<Integer> skipped = numbers.stream()
.skip(5)
.collect(Collectors.toList());
// [6, 7, 8, 9, 10]
3.6 peek调试 #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
.peek(n -> System.out.println("处理: " + n))
.map(n -> n * 2)
.peek(n -> System.out.println("结果: " + n))
.collect(Collectors.toList());
四、终端操作 #
4.1 collect收集 #
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 收集为List
List<String> list = names.stream().collect(Collectors.toList());
// 收集为Set
Set<String> set = names.stream().collect(Collectors.toSet());
// 收集为Map
Map<String, Integer> map = names.stream()
.collect(Collectors.toMap(name -> name, String::length));
// 分组
Map<Integer, List<String>> grouped = names.stream()
.collect(Collectors.groupingBy(String::length));
// 分区
Map<Boolean, List<String>> partitioned = names.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 3));
// 连接字符串
String joined = names.stream()
.collect(Collectors.joining(", "));
// Alice, Bob, Charlie
4.2 forEach遍历 #
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
names.forEach(System.out::println); // 简化写法
4.3 count计数 #
java
long count = names.stream()
.filter(s -> s.length() > 3)
.count();
4.4 reduce归约 #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 求和
int sum = numbers.stream()
.reduce(0, Integer::sum);
// 求最大值
Optional<Integer> max = numbers.stream()
.reduce(Integer::max);
// 求最小值
Optional<Integer> min = numbers.stream()
.reduce(Integer::min);
4.5 find查找 #
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 查找第一个
Optional<String> first = names.stream().findFirst();
// 查找任意一个(并行流更高效)
Optional<String> any = names.stream().findAny();
4.6 match匹配 #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 是否所有元素满足条件
boolean allMatch = numbers.stream().allMatch(n -> n > 0);
// 是否存在元素满足条件
boolean anyMatch = numbers.stream().anyMatch(n -> n > 3);
// 是否所有元素都不满足条件
boolean noneMatch = numbers.stream().noneMatch(n -> n < 0);
4.7 min和max #
java
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
Optional<Integer> min = numbers.stream().min(Integer::compare);
Optional<Integer> max = numbers.stream().max(Integer::compare);
五、并行流 #
5.1 创建并行流 #
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> parallel1 = numbers.parallelStream();
Stream<Integer> parallel2 = numbers.stream().parallel();
5.2 并行流操作 #
java
long count = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.count();
5.3 注意事项 #
- 确保操作是无状态的
- 避免共享可变状态
- 注意线程安全问题
六、原始类型流 #
6.1 IntStream #
java
// 创建
IntStream range = IntStream.range(1, 10); // [1, 10)
IntStream rangeClosed = IntStream.rangeClosed(1, 10); // [1, 10]
// 常用操作
int sum = IntStream.range(1, 101).sum();
OptionalDouble avg = IntStream.range(1, 101).average();
OptionalInt max = IntStream.range(1, 101).max();
// 转换
Stream<Integer> boxed = IntStream.range(1, 10).boxed();
6.2 LongStream和DoubleStream #
java
LongStream longStream = LongStream.range(1, 100);
DoubleStream doubleStream = DoubleStream.of(1.0, 2.0, 3.0);
七、总结 #
| 操作类型 | 方法 |
|---|---|
| 中间操作 | filter, map, sorted, distinct, limit, skip |
| 终端操作 | collect, forEach, count, reduce, find, match |
Stream要点:
- 中间操作惰性求值
- 终端操作触发执行
- Stream只能消费一次
- 合理使用并行流
最后更新:2026-03-26