Java 8 Stream Api 中的 peek 操作

简介: 本文介绍了Java中`Stream`的`peek`操作,该操作通过`Consumer<T>`函数消费流中的每个元素,但不改变元素类型。文章详细解释了`Consumer<T>`接口及其使用场景,并通过示例代码展示了`peek`操作的应用。此外,还对比了`peek`与`map`的区别,帮助读者更好地理解这两种操作的不同用途。作者为码农小胖哥,原文发布于稀土掘金。

2. peek

peek 操作接收的是一个 Consumer<T> 函数。顾名思义 peek 操作会按照 Consumer<T> 函数提供的逻辑去消费流中的每一个元素,同时有可能改变元素内部的一些属性。 这里我们要提一下这个 Consumer<T> 以理解 什么是消费。

2.1 什么是消费 (Consumer)

代码解读

复制代码

package java.util.function;

import java.util.Objects;

 
@FunctionalInterface
public interface Consumer<T> {
 
    void accept(T t);

     // 嵌套accept , 顺序为先执行 accept 后执行参数里的 after.accpet
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
 }

Consumer<T> 是一个函数接口。一个抽象方法 void accept(T t) 意为接受一个 T 类型的参数并将其消费掉。其实消费给我的感觉就是 “用掉” ,自然返回的就是 void 。 通常“用掉” T 的方式为两种:

  • T 本身的 void 方法  比较典型的就是 setter
  • 把 T 交给其它接口(类)的 void 方法进行处理  比如我们经常用的打印一个对象 System.out.println(T)

2.2 peek 操作演示

代码解读

复制代码

 Stream<String> stream = Stream.of("hello", "felord.cn");
   stream.peek(System.out::println);

如果你测试了上面给出的代码你会发现,压根不会按照逻辑跑。这是为啥子呢? 这是因为流的生命周期有三个阶段:

  • 起始生成阶段。
  • 中间操作会逐一获取元素并进行处理。 可有可无。所有中间操作都是惰性的,因此,流在管道中流动之前,任何操作都不会产生任何影响。
  • 终端操作。通常分为 最终的消费foreach 之类的)和 归纳collect)两类。还有重要的一点就是终端操作启动了流在管道中的流动。

所以应该改成下面:

代码解读

复制代码

 Stream<String> stream = Stream.of("hello", "felord.cn");
  List<String> strs= stream.peek(System.out::println).collect(Collectors.toLIst());

比如下图,我们给圆球加了一个框:

3. peek VS map

peek 操作 一般用于不想改变流中元素本身的类型或者只想操作元素的内部状态时;而 map 则用于改变流中元素本身类型,即从元素中派生出另一种类型的操作。这是他们之间的最大区别。 那么 peek 实际中我们会用于哪些场景呢?比如对 Stream<T> 中的 T 的某些属性进行批处理的时候用 peek 操作就比较合适。 如果我们要从 Stream<T>  中获取 T 的某个属性的集合时用 map 也就最好不过了。

4. 总结

我们今天了解 Streampeek 操作,同时也回顾了 Stream 的生命周期。也顺带对 Consumer<T> 函数进行了讲解。而且 和 map 相互做了比较,对各自的使用场景又做了说明。相信看过本文后你对它们会有更深的理解。


转载来源:https://juejin.cn/post/6844904004619616264

相关文章
|
14天前
|
Java API
详细解释一下Stream API中的sorted操作
详细解释一下Stream API中的sorted操作
76 1
|
25天前
|
Java 测试技术 API
Java Stream API:被低估的性能陷阱与优化技巧
Java Stream API:被低估的性能陷阱与优化技巧
230 114
|
25天前
|
Java API
深入理解Java Stream API:告别繁琐循环
深入理解Java Stream API:告别繁琐循环
202 104
|
28天前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
123 1
|
2月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
2月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
205 100
|
2月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
226 101
|
2月前
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
194 101
|
SQL 存储 JSON
ElasticSearch 查询与 Java API 实践(下)
ElasticSearch 查询与 Java API 实践
1117 0
ElasticSearch 查询与 Java API 实践(下)
|
存储 Java 数据建模
ElasticSearch 查询与 Java API 实践(中)
ElasticSearch 查询与 Java API 实践
401 0
ElasticSearch 查询与 Java API 实践(中)