java 8 Stream中操作类型和peek的使用
java 8 Stream中操作类型和peek的使用
简介
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
欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com
java 8 Stream中操作类型和peek的使用的更多相关文章
- Java中int类型和tyte[]之间转换及byte[]合并
JAVA基于位移的 int类型和tyte[]之间转换 [java] view plaincopy /** * 基于位移的int转化成byte[] * @param int number * @retu ...
- java 8 stream中的Spliterator简介
目录 简介 tryAdvance trySplit estimateSize characteristics 举个例子 总结 java 8 stream中的Spliterator简介 简介 Split ...
- 关于 Go 中 Map 类型和 Slice 类型的传递
关于 Go 中 Map 类型和 Slice 类型的传递 Map 类型 先看例子 m1: func main() { m := make(map[int]int) mdMap(m) fmt.Printl ...
- Python3.x中bytes类型和str类型深入分析
Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和b ...
- Java中日期类型和mysql中日期类型进行整合
1. java与mysql中日期.时间类型总结: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 mysql(版本:5.1.50)的时间日期类型如下: da ...
- java中XMLGregorianCalendar类型和Date类型之间的相互转换
import java.text.SimpleDateFormat;import java.util.Date;import java.util.GregorianCalendar;import ja ...
- 关于java同步包中ConcurrentLinkedQueue类的深入分析与理解
一,官方描写叙述 一个基于连接节点的无界线程安全队列.这个队列的顺序是先进先出.队列头部的元素是留在队列中时间最长的,队列尾部的元素是留在队列中时间最短的.新元素被插入到元素的尾部,队列从队列的头部检 ...
- MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...
- js中Boolean类型和Number类型的一些常见方法
Boolean类型 Boolean类型重写了valueOf() 方法, 返回基本布尔类型值true或false,重写了toString() 方法,返回基本字符串"true" 和 & ...
随机推荐
- C#如何正确的做深拷贝
估计很多人在网上看到各种各样的DeepClone实现, 例如: 1. 通过BinaryFormatter进行二进制序列化 这玩意儿序列化出来的东西还带namespace类型, 尺寸非常大, 调试一下就 ...
- 当const放在function声明后
#include <iostream> class MyClass { private: int counter; public: void Foo() { std::cout <& ...
- python 函数--迭代器
一.迭代协议: 可以被迭代要满足要求的就叫做可迭代协议.内部实现__iter__方法. iterable:可迭代的--对应的标志. 什么叫做迭代?:可以一个一个取值,就像for循环一样取值. 字符串, ...
- 《民国奇探》的弹幕有点逗比,用 Python 爬下来看看
电视剧<民国奇探>是一部充斥着逗比风的探案剧,剧中主要角色:三土.四爷.白小姐,三土这个角色类似于<名侦探柯南>中的柯南但带有搞笑属性,四爷则类似于毛利小五郎但有大哥范且武功高 ...
- Web Scraper 高级用法——使用 CouchDB 存储数据 | 简易数据分析 18
这是简易数据分析系列的第 18 篇文章. 利用 web scraper 抓取数据的时候,大家一定会遇到一个问题:数据是乱序的.在之前的教程里,我建议大家利用 Excel 等工具对数据二次加工排序,但还 ...
- 【Selenium07篇】python+selenium实现Web自动化:PO模型,PageObject模式!
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第七篇博 ...
- 开源运动的"圣经"——《大教堂与集市》读书笔记
作者:Eric S. Raymond 一.黑客圈简史 1.早期 (1)MIT 与 ITS "黑客"一词大约就起源于MIT的计算机文化. 从PDP-1时代开始,黑客文化的命运就和DE ...
- MyEclipse 10安装SVN插件subclipse
1. 下载SVN插件subclipse 下载地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?expandFolder=2240& ...
- 面试问了解Linux内存管理吗?10张图给你安排的明明白白!
文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 今天来带大家研究一下Linux内存管理.对于精通 CURD 的业务同学 ...
- Python logging日志打印
1.logging常用函数Logger.setLevel():设置日志级别Logger.addHandler()和Logger.removeHandler():添加和删除一个handlerLogger ...