跳转到内容

Java Stream与集合

来自代码酷

Java Stream与集合[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Java Stream API(Java 8+)是处理集合(Collection)数据的现代函数式编程工具,它允许开发者以声明式风格(描述"做什么"而非"如何做")高效处理数据。Stream与集合的主要区别在于:

  • 集合:存储和管理数据的容器(如List/Set)
  • Stream:对集合元素进行计算操作的流水线(不存储数据)

模板:Note

核心概念对比[编辑 | 编辑源代码]

特性 集合 Stream
是 | 否
外部迭代(for/iterator) | 内部迭代
支持增删改 | 只读(生成新Stream)
立即执行 | 惰性执行

基础操作[编辑 | 编辑源代码]

创建Stream[编辑 | 编辑源代码]

// 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();

// 直接创建
Stream<String> stream2 = Stream.of("x", "y", "z");

// 生成无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);

中间操作(Intermediate Operations)[编辑 | 编辑源代码]

操作 描述 示例
条件过滤 | stream.filter(s -> s.length() > 3)
元素转换 | stream.map(String::toUpperCase)
排序 | stream.sorted(Comparator.reverseOrder())
去重 | stream.distinct()

终端操作(Terminal Operations)[编辑 | 编辑源代码]

操作 描述 示例
遍历消费 | stream.forEach(System.out::println)
转为集合 | stream.collect(Collectors.toList())
归约计算 | stream.reduce(0, Integer::sum)
计数 | stream.count()

完整示例[编辑 | 编辑源代码]

import java.util.*;
import java.util.stream.*;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
        
        // 过滤长度>3的名字,转为大写,收集到List
        List<String> result = names.stream()
            .filter(name -> name.length() > 3)
            .map(String::toUpperCase)
            .collect(Collectors.toList());
            
        System.out.println(result); // 输出: [ALICE, CHARLIE, DAVID]
    }
}

并行处理[编辑 | 编辑源代码]

通过parallelStream()自动利用多核处理器:

long count = names.parallelStream()
    .filter(name -> name.length() > 4)
    .count();

graph LR A[集合] --> B[创建Stream] B --> C[中间操作] C --> D[终端操作] D --> E[结果] style C stroke:#f66,stroke-width:2px style D stroke:#090,stroke-width:2px

实际应用案例[编辑 | 编辑源代码]

场景:统计电商订单数据

List<Order> orders = getOrders();

// 计算所有有效订单的总金额(状态为COMPLETED)
double total = orders.stream()
    .filter(o -> o.getStatus() == OrderStatus.COMPLETED)
    .mapToDouble(Order::getAmount)
    .sum();

// 按用户分组统计订单数
Map<Long, Long> userOrderCount = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getUserId,
        Collectors.counting()
    ));

性能考虑[编辑 | 编辑源代码]

  • 小数据集:顺序流(stream())通常更快
  • 大数据集:并行流(parallelStream())有优势
  • 避免在流中修改外部状态(违反函数式原则)

并行加速比=T1Tp 其中T1是顺序时间,Tp是并行时间

常见误区[编辑 | 编辑源代码]

  1. 重复使用已关闭的Stream(会抛出IllegalStateException
  2. 混淆中间操作与终端操作
  3. 在流操作中依赖外部变量状态

模板:Tip

进阶主题[编辑 | 编辑源代码]

  • 原始类型流(IntStream/LongStream/DoubleStream)
  • 自定义Collector实现
  • 流与I/O操作结合(如Files.lines())
  • Reactive Streams(Java 9+)