java stream流(深入理解)

一.了解stream流

1.1stream的概念

  • Stream流(也叫Stream API)。它是从JDK8以后才有的一个新特性,是专业用于对集合或者数组进行便捷操作的。
  • Java Stream可以看作是对数据集合的一种高级封装,它将数据集合的操作抽象出来,允许我们以声明式的方式进行数据处理。与传统的集合操作相比,Java Stream更加灵活、可读性更强,并且可以充分利用多核处理器来进行并行处理。

2.2 Stream的特点和优势

  1. 声明式编程:使用Stream时,可以将数据处理过程描述为一系列转换操作,使代码更加简洁易读。
  2. 内部迭代:Stream处理数据时,无需显式使用迭代器,而是通过内部迭代器来进行遍历操作。
  3. 惰性求值:Stream提供了惰性求值的特性,只有当需要获取结果时才会进行实际的计算,可以减少不必要的计算开销。
  4. 并行处理:Stream可以利用多核处理器来进行并行处理,提高数据处理的效率。
  5. Java Stream提供了丰富的操作方法,包括过滤、映射、排序、去重、聚合等,可以对数据进行各种复杂的处理。

二.Stream流基本语法与常用的API

2.1Stream流中间方法

中间方法指的是:调用完方法之后其结果是一个新的Stream流,于是可以继续调用方法,这样一来就可以支持链式编程(或者叫流式编程)。

2.2Stream流终结方法

这些方法的特点是,调用完方法之后,其结果就不再是Stream流了,所以不支持链式编程。

2.3基本使用

接下里我们通过案例来体验一下有多方便

案例需求:有一个List集合,元素有"张三丰","张无忌","周芷若","赵敏","张强",找出姓张,且是3个字的名字,存入到一个新集合中去。

List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");
System.out.println(names);
  •   用传统方式来做,代码是这样的
// 找出姓张,且是3个字的名字,存入到一个新集合中去。
List<String> list = new ArrayList<>();
for (String name : names) {
    if(name.startsWith("张") && name.length() == 3){
        list.add(name);
    }
}
System.out.println(list);
  • 用Stream流来做,代码是这样的(想流水线一样,一句话就写完了)
List<String> list2 = names.stream().filter(s -> s.startsWith("张")).filter(a -> a.length()==3).collect(Collectors.toList());
System.out.println(list2);

三.Java Stream流的工作流程

Java Stream 流的工作流程可以概括为以下几个步骤:

  1. 创建数据源:首先,你需要有一个数据源,如集合或数组。通过调用 Collection.stream() 方法或 Arrays.stream() 方法,你可以将数据源转换为相应的流对象。
  2. 中间操作:一旦有了流对象,你可以对其进行一系列的中间操作。中间操作是指对数据进行过滤、映射、排序等操作,每个中间操作都会返回一个新的流。例如,你可以使用 .filter() 方法过滤掉不符合条件的数据,使用 .map() 方法对数据进行转换,使用 .sorted() 方法对数据进行排序等。
  3. 终止操作:在完成中间操作后,你可以进行终止操作来触发流的计算。终止操作是最后的操作,它会产生最终的结果或副作用。常见的终止操作包括使用 .forEach() 方法迭代流中的每个元素,使用 .collect() 方法将流的元素收集到一个集合中,使用 .reduce() 方法对流的元素进行归约等。
  4. 惰性求值和内部迭代:Stream 流的操作是惰性求值的,中间操作不会立即执行,而是等到终止操作时才进行计算。另外,Stream 流使用内部迭代来处理数据,这意味着你不需要手动编写迭代逻辑,而是将数据处理的工作交给了 Stream 内部来完成。
  5. 并行流处理:Stream 流提供了并行流(Parallel Stream)的支持,可以通过 .parallel() 方法将流转换为并行流,从而实现并行处理。并行流利用多线程来加速数据处理,适用于处理大量数据或需要并行计算的场景。

四.了解 Java Stream 流的原理

4.1为什么可以链式调用

返回自身:Stream 中的中间方法一般都会返回一个新的 Stream 对象,这个新的 Stream 对象可以继续调用其他方法。这种设计使得我们可以将多个方法调用连接在一起,形成一条连续的操作流水线。链式编程的特点是每个方法的返回值都是当前对象,这样就可以串联多个方法调用 

4.2Stream 接口:

Java Stream 的定义位于 java.util.stream.Stream 接口中。它是一个泛型接口,提供了用于操作数据流的各种方法。

4.2数据源和中间操作

Stream 是由一个数据源(如集合、数组等)和一系列中间操作组成的。中间操作包括 filter、map、flatMap、distinct、sorted、limit 等。这些中间操作可以通过调用 Stream 对象上的方法来进行链式调用。

4.3惰性求值

Stream 使用惰性求值的方式来处理数据。这意味着在执行中间操作时,并不会立即计算,而是将操作的逻辑保存起来。只有当执行终止操作(如 collect、forEach、count 等)时,才会触发实际的计算。

4.4StreamSpliterators

StreamSpliterators 是 Stream 中数据的生成器,它负责维护源数据的状态和分割数据流。流水线中的中间操作通常会涉及到 StreamSpliterators 进行数据处理和分割。

4.5Spliterator 接口

Spliterator 是一个用于遍历和分割数据源的接口,StreamSpliterators 实现了 Spliterator 接口。Spliterator 定义了一些方法,如 tryAdvance、forEachRemaining、trySplit 等,用于实现数据的遍历和分割。

4.6TerminalSink

TerminalSink 是 Stream 流的终止操作的实现,它接收 Stream 中的元素并生成最终的结果。TerminalSink 是一个 Sink 接口的实现类。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值