深入 Java Stream 流

ops/2025/1/22 17:29:18/

目录

一、Stream 流是什么,为啥它如此重要

二、Stream 流的创建

1. 通过集合创建

2. 通过数组创建

3. 使用 Stream.of () 方法

三、Stream 流的中间操作

1. 过滤(filter)

2. 映射(map)

3. 排序(sorted)

四、Stream 流的终端操作

1. 收集(collect)

2. 聚合(reduce)

3. 查找(findFirst、findAny 等)

五、并行流的应用

六、总结


在 Java 编程的领域中,Stream 流可谓是一项令人瞩目的特性,它为我们处理集合数据带来了全新的思路与高效的方式。Stream 流就像是一条数据处理的 “流水线”,让我们能够以一种简洁、声明式的风格对数据进行筛选、转换、聚合等操作。今天,咱们就一起深入探究 Java 的 Stream 流,通过丰富的代码示例来领略它的强大魅力。

一、Stream 流是什么,为啥它如此重要

想象一下,你有一堆杂乱无章的物品,需要对它们进行分类、筛选、统计等一系列操作。以往,我们可能需要编写冗长的循环代码来实现这些功能,不仅繁琐,而且容易出错。而 Stream 流就像是一个智能的 “助手”,它能够帮我们更优雅、更高效地完成这些任务。

Java 8 引入的 Stream 流,本质上是对集合数据进行函数式操作的一种抽象。它允许我们以一种类似于 SQL 语句的方式来处理集合数据,将数据处理逻辑与数据本身分离,使代码更加简洁、易读。通过 Stream 流,我们可以轻松地实现对集合的过滤、映射、排序、聚合等常见操作,大大提高了代码的可读性和可维护性。

二、Stream 流的创建

在使用 Stream 流之前,我们首先要学会如何创建它。Stream 流的创建方式多种多样,下面为大家介绍几种常见的创建方式。

1. 通过集合创建

Java 中的集合类都提供了stream()方法来创建一个顺序流,以及parallelStream()方法来创建一个并行流。并行流利用多核 CPU 的优势,能够同时处理多个数据元素,提高处理效率。

java">import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;public class StreamFromCollectionExample {public static void main(String[] args) {List<Integer> numbers = new ArrayList<>();numbers.add(1);numbers.add(2);numbers.add(3);numbers.add(4);numbers.add(5);// 创建顺序流Stream<Integer> sequentialStream = numbers.stream();// 创建并行流Stream<Integer> parallelStream = numbers.parallelStream();}
}

2. 通过数组创建

我们可以使用Arrays.stream()方法将数组转换为 Stream 流。

java">import java.util.Arrays;
import java.util.stream.Stream;public class StreamFromArrayExample {public static void main(String[] args) {int[] numbers = {1, 2, 3, 4, 5};Stream<int[]> streamOfArrays = Stream.of(numbers);// 对于基本类型数组,也可以使用专门的方法IntStream intStream = Arrays.stream(numbers);}
}

3. 使用 Stream.of () 方法

Stream.of()方法可以直接将一组元素转换为 Stream 流。

java">import java.util.stream.Stream;public class StreamOfExample {public static void main(String[] args) {Stream<String> stringStream = Stream.of("apple", "banana", "cherry");}
}

三、Stream 流的中间操作

Stream 流提供了一系列的中间操作,这些操作会返回一个新的 Stream 流,并且可以将多个中间操作串联起来,形成一个操作链。常见的中间操作包括过滤、映射、排序等。

1. 过滤(filter)

filter操作可以根据给定的条件筛选出符合条件的元素。

java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class StreamFilterExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());System.out.println("偶数: " + evenNumbers);}
}

在上述代码中,我们使用filter方法筛选出了列表中的偶数。

2. 映射(map)

map操作可以将 Stream 流中的每个元素按照指定的函数进行转换。

java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class StreamMapExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);List<Integer> squaredNumbers = numbers.stream().map(n -> n * n).collect(Collectors.toList());System.out.println("平方后的数字: " + squaredNumbers);}
}

这里我们使用map方法将列表中的每个数字转换为其平方。

3. 排序(sorted)

sorted操作可以对 Stream 流中的元素进行排序。

java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class StreamSortedExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);List<Integer> sortedNumbers = numbers.stream().sorted().collect(Collectors.toList());System.out.println("排序后的数字: " + sortedNumbers);}
}

在这个例子中,我们对列表中的数字进行了升序排序。如果需要降序排序,可以使用sorted(Comparator.reverseOrder())

四、Stream 流的终端操作

终端操作会消费 Stream 流,执行中间操作链,并返回一个结果。常见的终端操作包括收集、聚合、查找等。

1. 收集(collect)

collect操作可以将 Stream 流中的元素收集到一个集合中,或者进行其他形式的汇总。

java">import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class StreamCollectExample {public static void main(String[] args) {List<String> fruits = new ArrayList<>();fruits.add("apple");fruits.add("banana");fruits.add("cherry");List<String> upperCaseFruits = fruits.stream().map(String::toUpperCase).collect(Collectors.toList());System.out.println("转换为大写后的水果列表: " + upperCaseFruits);}
}

在上述代码中,我们将水果列表中的每个元素转换为大写,并收集到一个新的列表中。

2. 聚合(reduce)

reduce操作可以对 Stream 流中的元素进行聚合操作,例如求和、求积等。

java">import java.util.Arrays;
import java.util.List;public class StreamReduceExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().reduce(0, (a, b) -> a + b);System.out.println("数字之和: " + sum);}
}

这里我们使用reduce方法对列表中的数字进行求和,初始值为 0。

3. 查找(findFirst、findAny 等)

findFirst操作可以返回 Stream 流中的第一个元素,findAny操作可以返回 Stream 流中的任意一个元素(在并行流中,findAny可能会返回更高效的结果)。

java">import java.util.Arrays;
import java.util.List;
import java.util.Optional;public class StreamFindExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);Optional<Integer> firstNumber = numbers.stream().findFirst();firstNumber.ifPresent(System.out::println);}
}

在上述代码中,我们使用findFirst方法获取列表中的第一个元素,并通过ifPresent方法进行处理,避免了空指针异常。

五、并行流的应用

并行流利用多核 CPU 的优势,可以显著提高大数据集的处理效率。在使用并行流时,只需要将stream()方法替换为parallelStream()方法即可。

java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class ParallelStreamExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> squaredNumbers = numbers.parallelStream().map(n -> n * n).collect(Collectors.toList());System.out.println("并行处理后的平方数字: " + squaredNumbers);}
}

需要注意的是,并行流并不适用于所有场景,在处理小数据集或者存在共享资源的情况下,并行流可能会因为线程调度等开销而降低性能。因此,在实际应用中,需要根据具体情况进行权衡。

六、总结

通过今天的学习,我们深入了解了 Java 的 Stream 流,从它的创建方式,到丰富的中间操作和终端操作,以及并行流的应用。Stream 流为我们提供了一种简洁、高效的方式来处理集合数据,让代码更加优雅、易读。在实际编程中,合理运用 Stream 流能够大大提高开发效率,减少代码量,同时充分发挥多核 CPU 的性能优势。希望大家在今后的 Java 编程中,能够熟练掌握并运用 Stream 流,为自己的代码注入新的活力。如果在学习过程中遇到任何问题,欢迎随时交流,让我们一起在 Java 编程的道路上不断探索前行。


http://www.ppmy.cn/ops/152243.html

相关文章

Gitlab搭建npm仓库

由于图片和格式解析问题&#xff0c;为了更好阅读体验可前往 阅读原文 使用gitlab的仓库注册表特性需要版本14.0&#xff0c;如果你的版本比较低&#xff0c;请先根据自己的需求合理升级后再使用 npm私有仓库的搭建方式有很多种&#xff0c;比如使用docker(阅读此篇)&#xff…

【基础篇】什么是SQL注入,如何防止?

什么是 SQL 注入&#xff0c;如何防止&#xff1f; SQL 注入&#xff08;SQL Injection&#xff09;是一种常见的网络安全漏洞&#xff0c;它发生在 Web 应用程序中&#xff0c;当恶意用户在输入数据时&#xff0c;将恶意的 SQL 代码插入到输入中&#xff0c;从而导致应用程序…

C++ 中的最大值和最小值判断

1. 使用 std::numeric_limits<T>::max() 和 std::numeric_limits<T>::min() std::numeric_limits 是 C 标准库中的模板类&#xff0c;用于获取各种数据类型的最大值和最小值。它提供了一种通用的方式&#xff0c;适用于所有标准数据类型&#xff08;如 int、long、…

网创资源采集插件自动采集更新网站

现在的资源站越来越多人们对资源的需求也是越来越大但是对站长们来说对对资源的争议是比较耗时的比如大家想开一个网状的资源整合站又比较困难大家需要投入很多的人工经历但是我们如果使用插件自动化的采集发布实验全自动交易是一件非常理想的事情利用插件我们可以实现这一目的…

【算法笔记】力扣热题100(LeetCode hot-100)560. 和为 K 的子数组

力扣热题100&#xff08;LeetCode hot-100&#xff09;之 560. 和为 K 的子数组 本文主要记录算法思路&#xff0c;着急要答案的同学可以直接跳转到最后的代码。 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。子数…

社区版Dify实现文生视频 LLM+ComfyUI+混元视频

社区版Dify实现文生视频 LLMComfyUI混元视频 一、 社区版Dify实现私有化混元视频效果二、为什么社区版Dify可以在对话框实现文生视频&#xff1f;LLMComfyUI混元视频 实现流程图&#xff08;重点&#xff09;1. 文生视频模型支持ComfyUI2. ComfyUI可以轻松导出API实现封装3. Di…

1.2.神经网络基础

目录 1.2.神经网络基础 1.2.1.Logistic回归 1.2.2 梯度下降算法 1.2.3 导数 1.2.4 向量化编程 1.2.5 正向传播与反向传播 1.2.6.练习 1.2.神经网络基础 1.2.1.Logistic回归 1.2.1.1.Logistic回归 逻辑回归是一个主要用于二分分类类的算法。那么逻辑回归是给定一个x ,…

金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析

金融资产波动率建模在现代金融工程中具有重要地位&#xff0c;其应用涵盖风险管理、衍生品定价和投资组合优化等核心领域。本文着重探讨三种主流波动率建模方法&#xff1a;广义自回归条件异方差模型(GARCH)、Glosten-Jagannathan-Runkle-GARCH模型(GJR-GARCH)以及异质自回归模…