一、Stream API 核心概念
Stream 是 Java 8 引入的用于处理集合数据的抽象API,支持函数式编程和链式调用,特点是:
- 无存储:不存储数据,只描述计算过程
- 惰性求值:中间操作延迟执行,直到触发终端操作
- 可消费性:流只能被消费一次
二、Stream 操作分类
1. 流创建方法
方法名 | 作用描述 | 示例 |
---|
stream() | 从集合创建顺序流 | list.stream() |
parallelStream() | 从集合创建并行流 | list.parallelStream() |
Stream.of() | 从数组或元素创建流 | Stream.of("a", "b", "c") |
Arrays.stream() | 从数组创建流 | Arrays.stream(new int[]{1,2,3}) |
Stream.iterate() | 生成无限流(需配合limit ) | Stream.iterate(0, n -> n+1) |
Stream.generate() | 通过Supplier生成无限流 | Stream.generate(Math::random) |
2. 中间操作(Intermediate Operations)
方法名 | 作用描述 | 示例 |
---|
filter(Predicate) | 过滤符合条件的元素 | .filter(s -> s.length() > 3) |
map(Function) | 元素映射(1:1转换) | .map(String::toUpperCase) |
flatMap(Function) | 扁平化映射(1:N转换) | .flatMap(list -> list.stream()) |
distinct() | 去重 | .distinct() |
sorted() | 自然排序 | .sorted() |
sorted(Comparator) | 自定义排序 | .sorted((a,b) -> b.compareTo(a)) |
limit(long) | 截取前N个元素 | .limit(10) |
skip(long) | 跳过前N个元素 | .skip(5) |
peek(Consumer) | 观察元素但不修改流(调试用) | .peek(System.out::println) |
3. 终端操作(Terminal Operations)
方法名 | 作用描述 | 示例 |
---|
forEach(Consumer) | 遍历每个元素 | .forEach(System.out::println) |
collect(Collector) | 将流转换为集合或其他数据结构 | .collect(Collectors.toList()) |
toArray() | 将流转换为数组 | .toArray(String[]::new) |
reduce(...) | 聚合操作(如求和、拼接等) | .reduce(0, Integer::sum) |
min(Comparator) | 找最小值 | .min(Integer::compare) |
max(Comparator) | 找最大值 | .max(String::compareTo) |
count() | 统计元素数量 | .count() |
anyMatch(Predicate) | 至少一个元素匹配条件 | .anyMatch(s -> s.contains("a")) |
allMatch(Predicate) | 所有元素匹配条件 | .allMatch(s -> s.length() > 2) |
noneMatch(Predicate) | 没有元素匹配条件 | .noneMatch(s -> s.startsWith("z")) |
findFirst() | 返回第一个元素(Optional) | .findFirst() |
findAny() | 返回任意元素(并行流中高效) | .findAny() |
4. Collectors 工具类常用方法
方法名 | 作用描述 | 示例 |
---|
toList() | 收集到List | Collectors.toList() |
toSet() | 收集到Set | Collectors.toSet() |
toMap(...) | 收集到Map(需指定键值生成函数) | Collectors.toMap(k->k, v->v) |
joining() | 拼接字符串 | Collectors.joining(", ") |
groupingBy(...) | 按条件分组 | Collectors.groupingBy(User::getAge) |
partitioningBy(...) | 按布尔条件分区 | Collectors.partitioningBy(s->s.length()>5) |
summingInt() | 对整型字段求和 | Collectors.summingInt(User::getAge) |
averagingDouble() | 计算双精度平均值 | Collectors.averagingDouble(...) |
counting() | 统计元素数量 | Collectors.counting() |
三、典型使用场景
1. 数据转换
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
2. 过滤与聚合
int total = orders.stream()
.filter(o -> o.getPrice() > 100)
.mapToInt(Order::getQuantity)
.sum();
3. 分组统计
Map<Department, List<Employee>> deptMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
4. 并行处理
List<Result> results = dataList.parallelStream()
.map(this::processData) // 并行计算
.collect(Collectors.toList());
四、注意事项
- 流只能消费一次:重复操作会抛出
IllegalStateException
- 空指针安全:使用
Optional
处理可能为null的结果 - 并行流线程安全:确保操作是线程安全的或无状态的
- 性能权衡:小数据量时顺序流可能更快,大数据量考虑并行流
评论 (0)