当前位置: 首页 > news >正文

Java Stream流详解:用法与常用API实战

1. 什么是Stream流?

Java 8 引入了 Stream API,它提供了一种高效、声明式的方式来处理集合数据。Stream 不是数据结构,而是对数据源(如集合、数组等)进行高效聚合操作(如过滤、映射、排序等)的工具。

Stream 的特点:

  • 不存储数据:Stream 本身不存储元素,它只是从数据源(如集合)获取数据并进行操作。

  • 不修改源数据:Stream 的操作不会改变原始数据源,而是生成新的流。

  • 惰性执行:许多 Stream 操作(如 filtermap)是惰性的,只有在终端操作(如 collectforEach)触发时才会执行。

  • 可并行化:Stream 可以轻松转换为并行流(parallelStream),以利用多核 CPU 提升性能。


2. Stream 的创建方式

Stream 可以通过多种方式创建:

(1)从集合创建

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Stream<String> stream = names.stream();  // 顺序流
Stream<String> parallelStream = names.parallelStream();  // 并行流

(2)从数组创建

String[] languages = {"Java", "Python", "C++", "JavaScript"};
Stream<String> stream = Arrays.stream(languages);

(3)使用 Stream.of() 创建

Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);

(4)使用 Stream.generate() 或 Stream.iterate()

// 生成 5 个随机数
Stream<Double> randomNumbers = Stream.generate(Math::random).limit(5);// 生成 1, 3, 5, 7, 9(无限流,需要 limit 限制)
Stream<Integer> oddNumbers = Stream.iterate(1, n -> n + 2).limit(5);

3. Stream 常用 API 及案例

Stream 的操作分为 中间操作(Intermediate Operations) 和 终端操作(Terminal Operations)

(1)中间操作

① filter(Predicate<T>):过滤元素
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> longNames = names.stream().filter(name -> name.length() > 4)  // 只保留长度 >4 的名字.collect(Collectors.toList());  // 收集为 ListSystem.out.println(longNames);  // [Alice, Charlie, David]
② map(Function<T, R>):映射转换

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream().map(n -> n * n)  // 计算平方.collect(Collectors.toList());System.out.println(squares);  // [1, 4, 9, 16, 25]
③ flatMap(Function<T, Stream<R>>):扁平化流
List<List<Integer>> nestedList = Arrays.asList(Arrays.asList(1, 2, 3),Arrays.asList(4, 5, 6)
);List<Integer> flatList = nestedList.stream().flatMap(List::stream)  // 将多个 List 合并为一个 Stream.collect(Collectors.toList());System.out.println(flatList);  // [1, 2, 3, 4, 5, 6]
④ sorted() / sorted(Comparator<T>):排序
List<String> names = Arrays.asList("Bob", "Alice", "David", "Charlie");
List<String> sortedNames = names.stream().sorted()  // 自然排序(字典序).collect(Collectors.toList());System.out.println(sortedNames);  // [Alice, Bob, Charlie, David]// 按长度排序
List<String> lengthSortedNames = names.stream().sorted(Comparator.comparingInt(String::length)).collect(Collectors.toList());System.out.println(lengthSortedNames);  // [Bob, Alice, David, Charlie]
⑤ distinct():去重
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3, 4);
List<Integer> distinctNumbers = numbers.stream().distinct().collect(Collectors.toList());System.out.println(distinctNumbers);  // [1, 2, 3, 4]

(2)终端操作

① forEach(Consumer<T>):遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
// 输出:
// Alice
// Bob
// Charlie
② collect(Collector<T, A, R>):收集结果
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Set<String> nameSet = names.stream().collect(Collectors.toSet());Map<String, Integer> nameLengthMap = names.stream().collect(Collectors.toMap(name -> name,  // keyname -> name.length()  // value));System.out.println(nameSet);  // [Alice, Bob, Charlie]
System.out.println(nameLengthMap);  // {Alice=5, Bob=3, Charlie=7}
③ reduce(BinaryOperator<T>):归约
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, (a, b) -> a + b);  // 计算总和System.out.println(sum);  // 15
④ count():计数
long count = Stream.of(1, 2, 3, 4, 5).count();
System.out.println(count);  // 5
⑤ anyMatch() / allMatch() / noneMatch():匹配检查
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);  // 是否有偶数?
boolean allPositive = numbers.stream().allMatch(n -> n > 0);   // 是否全为正数?
boolean noneNegative = numbers.stream().noneMatch(n -> n < 0); // 是否没有负数?System.out.println(hasEven);      // true
System.out.println(allPositive);  // true
System.out.println(noneNegative); // true

4. 综合案例

案例1:统计员工薪资

List<Employee> employees = Arrays.asList(new Employee("Alice", 5000),new Employee("Bob", 6000),new Employee("Charlie", 7000)
);// 计算平均薪资
double avgSalary = employees.stream().mapToInt(Employee::getSalary)  // 转为 IntStream.average().orElse(0.0);System.out.println("平均薪资:" + avgSalary);

案例2:分组统计

List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");// 按单词长度分组
Map<Integer, List<String>> wordsByLength = words.stream().collect(Collectors.groupingBy(String::length));System.out.println(wordsByLength);
// 输出:{5=[apple], 6=[banana, cherry], 4=[date], 10=[elderberry]}

案例3:并行流加速计算

List<Integer> bigList = IntStream.range(1, 10_000_000).boxed().collect(Collectors.toList());long startTime = System.currentTimeMillis();
long sum = bigList.paralleltream()  // 并行流.mapToLong(Integer::longValue).sum();
long endTime = System.currentTimeMillis();System.out.println("总和:" + sum);
System.out.println("耗时:" + (endTime - startTime) + "ms");

5. 总结

  • Stream 提供了一种高效、声明式处理集合的方式,比传统的 for 循环更简洁。

  • 中间操作(如 filtermap)返回新的流,终端操作(如 collectforEach)触发计算。

  • 并行流parallelStream)可以加速大数据集处理。

  • 合理使用 mapfilterreduce 等操作,可以写出更优雅的代码。

http://www.xdnf.cn/news/1268371.html

相关文章:

  • Tob大客户销售面试经验
  • 数据安全与隐私保护:企业级防护策略与技术实现
  • DBSCAN聚类算法实战全解析
  • 时序分解 | MATLAB实现SAO-VMD雪消融算法优化变分模态分解
  • Python 属性描述符(描述符用法建议)
  • 词向量可视化:用TensorBoard或PCA探索词向量空间
  • RecyclerView 中 ViewHolder
  • Datawhale+AI夏令营_让AI读懂财报PDF task2深入赛题笔记
  • 学习Java的Day28
  • 常用信号深度解析(SIGINT、SIGPIPE、SIGALRM、SIGTERM等)
  • Android 锁屏图标的大小修改
  • 线上排查问题的一般流程是怎么样的?
  • [激光原理与应用-207]:光学器件 - 光纤种子源激光器常用元器件
  • python---类型别名
  • 新手小白使用jQuery在实际开发中常用到的经验
  • ABP VNext + Akka.NET:高并发处理与分布式计算
  • 从 AI 到实时视频通道:基于模块化架构的低延迟直播全链路实践
  • Vuex与Pinia对比,以及技术选型
  • 《C++进阶之继承多态》【普通类/模板类的继承 + 父类子类的转换 + 继承的作用域 + 子类的默认成员函数】
  • 10.final, finally, finalize的区别
  • 【自动化运维神器Ansible】playbook自动化部署Nginx案例解析:助力从零构建高效Web服务
  • 2025 大语言模型系统学习路线:从基础到部署与优化的全方位指南(含权威资源与项目实战)
  • 4深度学习Pytorch-神经网络--损失函数(sigmoid、Tanh、ReLU、LReLu、softmax)
  • IDEA快捷键壁纸分享
  • 光伏面板损伤检出率↑91%!陌讯多模态识别算法在无人机巡检的落地实践
  • AI 破解数据质量难题:从混乱到可信的智能进化之路
  • 计算机网络1-6:计算机网络体系结构
  • webwork的学习
  • 非常简单!从零学习如何免费制作一个lofi视频
  • 香橙派 RK3588 部署千问大模型 Qwen2-VL-2B 推理视频