[从零开始学习JAVA] Stream流

前言:

本文我们将学习Stream流,他就像流水线一样,可以对我们要处理的对象进行逐步处理,最终达到我们想要的效果,是JAVA中的一大好帮手,值得我们了解和掌握。(通常和lambda 匿名内部类 方法引用相配合)

Stram流:

Stream流的核心思想是函数式编程(注意返回值必须是对象本身才能),它倡导将数据处理过程看作是一系列的转换操作。这种思想与传统的命令式编程方式不同,传统的命令式编程方式强调对数据的直接操作,而函数式编程则更加注重对数据的转换和操作过程。

在使用Stream流时,我们可以将数据源(如集合或数组)看作是一组元素的流,通过一系列的中间操作(如过滤、映射、排序等),最终到达终止操作(如匹配、归约、收集等)来处理数据。

设计目标:

Stream流的设计目标是提供一种简洁、高效的数据处理方式,使得代码更加可读、易于理解和维护。它的思想是将数据处理过程分解为多个步骤,每个步骤都是一种转换操作,可以对数据进行过滤、映射、排序等操作,最终得到所需要的结果。

通过使用Stream流,我们可以避免传统的循环和条件判断,将复杂的数据处理逻辑转化为简洁、清晰的方法链式调用,使得代码更加简洁和可读。

另外,Stream流还支持并行处理,可以将大数据集划分为多个子集并行执行操作,提高处理效率。这种并行处理的方式可以很好地利用多核处理器的优势,使得数据处理更加高效。

总而言之,Stream流的思想是通过函数式编程的方式,将数据处理过程看作是一系列的转换操作,实现简洁、高效和易于理解的数据处理。它的设计目标是提供一种优雅和强大的数据处理方式,使得开发人员能够更加专注于数据转换的逻辑,而无需关心底层的迭代和条件判断。一般情况下,Stream流会搭配Lambda表达式一起运用,以此来简化集合和数组的操作。

使用步骤:

举例:

例如我们想在一堆存储在list中的数据中找到首字为"张"的数据,按照传统的写法来讲,我们需要手动遍历每一个数据,再利用list中的API进行判断首字母,但是Stream流的出现,大大便捷了我们的操作

复制代码
import java.util.ArrayList;
 
public class test01 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("赵敏");
        list1.add("张强");
        list1.add("刘三丰");
 
        //传统方法
        for (String s : list1) {
            if(s.startsWith("张"))
            {
                System.out.println(s);
            }
        }
        //直接调用stream流
        list1.stream().filter(name->name.startsWith("张")).forEach(name->System.out.println(name));
 
    }
}

从这个例子中我们可以总结出调用stream流的两步骤:

1.先得到一条Stream流,并把数据放上去。

2.利用Stream流中的各种API进行操作。(可以通过匿名内部类/lambda来实现)

  1. filter(Predicate<T> predicate):根据指定的条件过滤流中的元素,返回一个新的流。

  2. map(Function<T, R> mapper):对流中的每个元素进行映射操作,返回一个新的流,新流中的元素为映射后的结果。

  3. sorted():对流中的元素进行默认排序。

  4. sorted(Comparator<T> comparator):对流中的元素按照指定的规则进行排序。

  5. distinct():去除流中的重复元素,返回一个新的流。

  6. limit(long maxSize):截断流,获取前几个元素。

  7. skip(long n):跳过指定数量的元素,返回一个新的流。

  8. forEach(Consumer<T> action):对流中的每个元素执行指定的操作。

  9. collect(Collector<T, A, R> collector):将流中的元素收集到一个结果集合中。

  10. anyMatch(Predicate<T> predicate):判断流中是否有满足指定条件的元素。

  11. allMatch(Predicate<T> predicate):判断流中的所有元素是否都满足指定条件。

  12. noneMatch(Predicate<T> predicate):判断流中是否没有满足指定条件的元素。

  13. findFirst():返回流中的第一个元素。

  14. findAny():返回流中的任意一个元素。

  15. reduce(BinaryOperator<T> accumulator):将流中的元素按照指定的规约操作进行归约。

  16. parallelStream():返回一个并行流,可以并行地处理流中的元素。

使用Stream流的注意事项:

  1. Stream流是一次性使用的:一旦对Stream流进行终止操作(如forEach、collect等),就不能再对同一个Stream流进行其他操作。如果需要对同一组数据进行多个处理步骤,需要创建新的Stream流。

  2. 注意流的顺序:Stream流的中间操作顺序是很重要的,它们会按照顺序被应用到数据上。因此,在对流进行操作时,请确保中间操作的顺序是正确的,以避免出现错误的结果。

  3. 及早终止流:Stream流提供了许多终止操作,如forEach、collect、reduce等。在使用这些终止操作时,应尽量避免无限循环或大量计算,及早终止流以避免性能问题。

  4. 注意流的惰性求值:Stream流采用惰性求值的方式,即在终止操作之前,中间操作不会立即执行。这种机制可以提高性能,但也需要注意在需要及时执行的情况下使用及时触发的操作如count、findFirst等。

  5. 避免空指针异常:在对流进行操作时,需要注意空值(null)的情况,使用过滤操作时,需要考虑到空元素的处理,避免出现空指针异常。

  6. 并行流需谨慎使用:Stream流支持并行处理,可以通过parallelStream方法来获得并行流。但在使用并行流时,需要注意线程安全和性能问题,确保代码在并行执行时不会出现竞态条件或导致性能下降。

  7. 适度使用流操作:Stream流提供了丰富的操作方法,但并不意味着所有情况下都应该使用流操作。在简单的数据处理场景中,使用传统的循环方式可能更加直观和高效。

相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习