1.引言

  如果你试图对流操作中的流水线进行调试, 了解stream流水线每个操作之前和操作之后的中间值, 该如何去做?

  首先我们看一个例子, 使用forEach将流操作的结果打印出来.

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 public class PeekTestOne {
7 public static void main(String[] args) {
8 List<Integer> list = Arrays.asList(4, 7, 9, 11, 12);
9 list.stream()
10 .map(x -> x + 2)
11 .filter(x -> x % 2 != 0)
12 .limit(2)
13 .forEach(System.out::println);
14 }
15 }
16 输出结果如下:
17 9
18 11

  可以很明显的看出, 一旦调用了forEach操作, 整个流就会恢复运行.并不能很好的帮助我们了解Stream流水线中的每个操作(如:map,filter,limit等)产生的输出.

  再来看一个例子

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 public class PeekTestTwo {
7 public static void main(String[] args) {
8 Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream();
9 stream.peek(System.out::println);
10
11 }
12 }
13 这段代码是想打印stream中的值,却没有任何输出.

2.中间操作和终止操作

  中间操作是流水线中的数据进行加工的, 它是一个懒操作, 并不会马上执行, 需要等待有终止操作的时候才会执行.

  终止操作是Stream的启动操作, 当有终止操作的时候, Stream才会真正的开始执行.

  因此, 这里可以解释上面的peek操作是一个中间操作, 所以没有任何输出.

3.使用peek进行debug操作

peek的设计初衷就是在流的每个元素恢复运行之前的时候插入一个执行操作. 它不想forEach那样恢复整个流的运行操作. 而是在一个元素上完成操作之后, 它只会将操作顺承到流水线的下一个操作. 它能够将中间变量的值输出到日志. 有效的帮助我们了解流水线的每一步操作的输出值.如下图:

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 public class PeekTestThree {
7 public static void main(String[] args) {
8 List<Integer> list = Arrays.asList(4, 7, 9, 11, 12);
9 list.stream()
10 .peek(x -> System.out.println("stream: " + x))
11 .map(x -> x + 2)
12 .peek(x -> System.out.println("map: " + x))
13 .filter(x -> x % 2 != 0)
14 .peek(x -> System.out.println("filter: " + x))
15 .limit(2)
16 .peek(x -> System.out.println("limit: " + x))
17 .collect(toList());
18 }
19 }
20 输出结果如下:
21 stream: 4
22 map: 6
23 stream: 7
24 map: 9
25 filter: 9
26 limit: 9
27 stream: 9
28 map: 11
29 filter: 11
30 limit: 11
31
32 Process finished with exit code 0

4.peek和map的区别

  使用peek操作流,流中的元素没有改变。

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 public class PeekAndMapTestOne {
7 public static void main(String[] args) {
8 Arrays.asList("a","b")
9 .stream()
10 .peek(x -> x.toUpperCase())
11 .forEach(System.out::println);
12 }
13 }
14 输出:
15 a
16 b
17
18 Process finished with exit code 0

  使用map操作流,流中的元素有改变。

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 public class PeekAndMapTestTwo {
7 public static void main(String[] args) {
8 Arrays.asList("a","b")
9 .stream()
10 .map(x -> x.toUpperCase())
11 .forEach(System.out::println);
12 }
13 }
14 输出:
15 A
16 B
17
18 Process finished with exit code 0

  可以通过上面两个例子看出,map操作是对元素进行了转换。

  注意:peek对一个对象进行操作的时候,对象不变,但是可以改变对象里面的值.如下:

 1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/5/28
5 */
6 @Getter
7 @Setter
8 @AllArgsConstructor
9 @ToString
10 public class Person {
11
12 private String id;
13 private String name;
14
15 }
16 ----------------------------------------------------------------------------
17 /**
18 * @author lyh
19 * @version v-1.0.0
20 * @since 2021/5/28
21 */
22 public class PeekAndMapTestThree {
23 public static void main(String[] args) {
24 Arrays.asList(new Person("001","zs"),new Person("002","ls"))
25 .stream().peek(p -> p.setId("000")).forEach(System.out::println);
26 }
27 }
28 输出:
29 Person(id=000, name=zs)
30 Person(id=000, name=ls)
31
32 Process finished with exit code 0

  peek的定义

1 Stream<T> peek(Consumer<? super T> action);

  peek方法接收一个Consumer的入参. 了解λ表达式的应该明白 Consumer的实现类应该只有一个方法,该方法返回类型为void. 它只是对Stream中的元素进行某些操作,但是操作之后的数据并不返回到Stream中,所以Stream中的元素还是原来的元素.

  map的定义

1 <R> Stream<R> map(Function<? super T, ? extends R> mapper);

  map方法接收一个Function作为入参. Function是有返回值的, 这就表示map对Stream中的元素的操作结果都会返回到Stream中去.

​   觉得此文不错, 点赞+转发+关注, 本人非常感谢!

Stream中的Peek操作的更多相关文章

  1. Java 8 Stream Api 中的 peek 操作

    1. 前言 我在Java8 Stream API 详细使用指南[1] 中讲述了 [Java 8 Stream API]( "Java 8 Stream API") 中 map 操作 ...

  2. Stream流的这些操作,你得知道,对你工作有很大帮助

    Stream流 Stream(流)是一个来自数据源的元素队列并支持聚合操作: 元素是特定类型的对象,形成一个队列. Java中的Stream并不会存储元素,而 是按需计算. 数据源 流的来源. 可以是 ...

  3. java 8 Stream中操作类型和peek的使用

    目录 简介 中间操作和终止操作 peek 结论 java 8 Stream中操作类型和peek的使用 简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢 ...

  4. Java8中的流操作-基本使用&性能测试

    为获得更好的阅读体验,请访问原文:传送门 一.流(Stream)简介 流是 Java8 中 API 的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).这有点儿 ...

  5. Java8 Stream流API常用操作

    Java版本现在已经发布到JDK13了,目前公司还是用的JDK8,还是有必要了解一些JDK8的新特性的,例如优雅判空的Optional类,操作集合的Stream流,函数式编程等等;这里就按操作例举一些 ...

  6. 【JDK8】Java8 Stream流API常用操作

    Java版本现在已经发布到JDK13了,目前公司还是用的JDK8,还是有必要了解一些JDK8的新特性的,例如优雅判空的Optional类,操作集合的Stream流,函数式编程等等;这里就按操作例举一些 ...

  7. JAVA8之lambda表达式具体解释,及stream中的lambda使用

    前言: 本人也是学习lambda不久,可能有些地方描写叙述有误,还请大家谅解及指正! lambda表达式具体解释 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.l ...

  8. java中的集合操作类(未完待续)

    申明: 实习生的肤浅理解,如发现有错误之处.还望大牛们多多指点 废话 事实上我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList ...

  9. loadrunner中文件的操作

    loadrunner中文件的操作 我们可以使用fopen().fscanf().fprintf().fclose()函数进行文件操作,但是因为LoadRunner不支持FILE数据类型,所以我们需要做 ...

随机推荐

  1. 认识Git并了解Git的基本知识

    目录 认识Git 版本控制 版本控制的发展史 安装Git Git的核心概念 Git的使用原理 Git的工作流程 Git的基本流程 Git与SVN的区别 Git的基本使用 初始化Git 创建一个Git仓 ...

  2. 《C++ primer》学习笔记整理

    简介 本笔记目前已包含<C++ Primer>中的绝大部分内容,但尚有部分小节有所缺漏,如 19.1.19.2 节的笔记尚未整理,会持续更新. 本项目中的学习笔记是在学完一章内容后,对其要 ...

  3. Day02_14_可变长参数

    Java 可变参数 一个方法中只能有一个可变参数 它必须是该方法的最后一个形参(必须放在参数列表最后一个的位置) 传递给可变参数的数据类型必须一致 实例 public class 可变长参数 { pu ...

  4. 不一样的角度理解Vue组件

    什么是组件 以Java.C#等面向对象编程语言的角度去理解Vue组件,能够发现组件和面向对象编程的方式和风格很相似.一切事物皆为对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽 ...

  5. LinearDiscriminantAnalysis参数、属性和方法

    [LDA]线性判别分析 参数: solver:一个字符串,指定了求解最优化问题的算法,可以为如下的值. 'svd':奇异值分解.对于有大规模特征的数据,推荐用这种算法. 'lsqr':最小平方差,可以 ...

  6. 工厂模式之简单工厂模式,head first设计模式

    简单设计模式比较简单,15分钟的时间,跟着我做,十几分钟学会简单设计模式,开始吧: 1.使用new实例化一个对象时,你肯定知道这种代码缺少弹性,绑定着具体的类会导致代码更加脆弱,简单工厂模式就是针对接 ...

  7. WordPress伪静态规则设置

    伪静态:即网站本身是动态网页如.php..asp..aspx等格式,而这类网页还带"?"加参数来读取数据库.开启伪静态后,动态网页即被转换重写成静态网页类型页面. WordPres ...

  8. WordPress 缩率图学习笔记

    WordPress 缩率图学习笔记 Wordpress在生成缩略图的过程中,有两种不同的规则 缩放模式:缩放模式就是将图片等比例缩小,且新生成的缩略图长度或高度两者之中,有一个是你设置的缩略图的尺寸 ...

  9. 【接口参数解析BUG】SpringMVC接口参数解析

    今天遇到一个BUG,前端传递数字数组时,后端使用字符串类型去接收,结果无法接收到,代码如下 问题: GET请求: 前端: configJsonArray:[1,2] 后端: private Strin ...

  10. ThinkPHP5 利用.htaccess文件的 Rewrite 规则隐藏URL中的 index.php

    1.首先修改Apache的httpd.conf文件. 确认httpd.conf配置文件中加载了mod_rewrite.so 模块,加载的方法是去掉mod_rewrite.so前面的注释#号 讲http ...