Stream API [Java]

Marimo_z
2025-05-27 / 0 评论 / 2 阅读 / 正在检测是否收录...

一、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()生成无限流(需配合limitStream.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()收集到ListCollectors.toList()
toSet()收集到SetCollectors.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());

四、注意事项

  1. 流只能消费一次:重复操作会抛出IllegalStateException
  2. 空指针安全:使用Optional处理可能为null的结果
  3. 并行流线程安全:确保操作是线程安全的或无状态的
  4. 性能权衡:小数据量时顺序流可能更快,大数据量考虑并行流
1

评论 (0)

取消