Java 8 Stream操作类型及peek示例解析
作者:flydean程序那些事 发布时间:2021-07-17 20:42:08
简介
java 8 stream作为流式操作有两种操作类型,中间操作和终止操作。这两种有什么区别呢?
我们看一个peek的例子:
Stream<String> stream = Stream.of("one", "two", "three","four");
stream.peek(System.out::println);
上面的例子中,我们的本意是打印出Stream的值,但实际上没有任何输出。
为什么呢?
中间操作和终止操作
一个java 8的stream是由三部分组成的。数据源,零个或一个或多个中间操作,一个或零个终止操作。
中间操作是对数据的加工,注意,中间操作是lazy操作,并不会立马启动,需要等待终止操作才会执行。
终止操作是stream的启动操作,只有加上终止操作,stream才会真正的开始执行。
所以,问题解决了,peek是一个中间操作,所以上面的例子没有任何输出。
peek
我们看下peek的文档说明:peek主要被用在debug用途。
我们看下debug用途的使用:
Stream.of("one", "two", "three","four").filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
上面的例子输出:
Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
上面的例子我们输出了stream的中间值,方便我们的调试。
为什么只作为debug使用呢?我们再看一个例子:
Stream.of("one", "two", "three","four").peek(u -> u.toUpperCase())
.forEach(System.out::println);
上面的例子我们使用peek将element转换成为upper case。然后输出:
one
two
three
four
可以看到stream中的元素并没有被转换成大写格式。
再看一个map的对比:
Stream.of("one", "two", "three","four").map(u -> u.toUpperCase())
.forEach(System.out::println);
输出:
ONE
TWO
THREE
FOUR
可以看到map是真正的对元素进行了转换。
当然peek也有例外,假如我们Stream里面是一个对象会怎么样?
@Data
@AllArgsConstructor
static class User{
private String name;
}
List<User> userList=Stream.of(new User("a"),new User("b"),new User("c")).peek(u->u.setName("kkk")).collect(Collectors.toList());
log.info("{}",userList);
输出结果:
10:25:59.784 [main] INFO com.flydean.PeekUsage - [PeekUsage.User(name=kkk), PeekUsage.User(name=kkk), PeekUsage.User(name=kkk)]
我们看到如果是对象的话,实际的结果会被改变。
为什么peek和map有这样的区别呢?
我们看下peek和map的定义:
Stream<T> peek(Consumer<? super T> action)
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
peek接收一个Consumer,而map接收一个Function。
Consumer是没有返回值的,它只是对Stream中的元素进行某些操作,但是操作之后的数据并不返回到Stream中,所以Stream中的元素还是原来的元素。
而Function是有返回值的,这意味着对于Stream的元素的所有操作都会作为新的结果返回到Stream中。
这就是为什么peek String不会发生变化而peek Object会发送变化的原因。
结论
我们在本文中讲解了stream的两个操作类型,并总结了peek的使用。希望大家能够掌握。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/stream-peek
来源:https://www.cnblogs.com/flydean/p/java-8-stream-peek.html


猜你喜欢
- 背景我们在android超级优化-线程监控与线程统一可以知道,我们能够通过asm插桩的方式,进行了线程的监控与线程的统一,通过一系列的黑科技
- mybatis count()按条件查询1、sql count()函数count()函数返回匹配指定条件的行数。sql count(colu
- 题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。经典题,不多说,直接上代码import java.
- 前言不久之前,部门进行了一次代码评审。代码整体比较简单,该吹B的地方都已经吹过了,无非是些if else的老问题而已。当翻到一段定时任务的一
- // 声明LocationManager对象 LocationManager loctionManager; // 通过系统服务,取得Loc
- 这个是SpringBoot的Maven插件,主要用来打包的,通常打包成jar或者war文件。其中goal标签可以有5个值:repackage
- 总结一下java使用http发送post的方法:1、post请求用于发送json 格式的参数:/** * post请求(用于请
- 一、概念HttpClientAndroid 6中移除(API数量多扩展困难)。HttpURLConnection目前官方集成的。OKHttp
- 微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面我们就来简单的描述下接入公众号的步骤:1、首先你需要一
- 一、ArrayListArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayList是一个泛型类,可以存放任意类型
- 前言:来这家公司上班后,开始使用Git作为项目版本控制系统,由于以前用的是SVN,所以对Git也就简单学习了一下。但是,实践出真知,当开始使
- 本文实例讲述了C#实现基于IE内核的简单浏览器。分享给大家供大家参考。具体如下:Form1.cs如下:using System;using
- 这篇文章主要介绍了Spring-boot的debug调试代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 一,SQL注入–1,需求–1,利用jdbc查询user的信息,如果信息正确就登录,否则提示错误–1,创建user表,指定字段id name
- 此处网上最多的做法是需要修改tomcat的参数配置大致如下:<Connector port="8080" prot
- @ConfigurationProperties作用:用于获取配置文件中的属性定义并绑定到javaBean属性中举个栗子:配置文件mycar
- 说起双亲委派模型,不得不说一下类加载器。类加载器是什么?当我们编译Java类时,JVM会创建与平台和机器无关的字节码。字节码存储在.clas
- 一、安装activeMQLinux环境ActiveMQ部署方法:https://www.aspxhome.com/article/16232
- 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Ap
- SpringBoot JPA分页查询指定列并返回指定实体用习惯Mybatis,没用过jpa 真是各种踩坑了脑壳疼,一个分页弄老半天,原来就一