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的使用的更多相关文章

  1. Java中int类型和tyte[]之间转换及byte[]合并

    JAVA基于位移的 int类型和tyte[]之间转换 [java] view plaincopy /** * 基于位移的int转化成byte[] * @param int number * @retu ...

  2. java 8 stream中的Spliterator简介

    目录 简介 tryAdvance trySplit estimateSize characteristics 举个例子 总结 java 8 stream中的Spliterator简介 简介 Split ...

  3. 关于 Go 中 Map 类型和 Slice 类型的传递

    关于 Go 中 Map 类型和 Slice 类型的传递 Map 类型 先看例子 m1: func main() { m := make(map[int]int) mdMap(m) fmt.Printl ...

  4. Python3.x中bytes类型和str类型深入分析

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和b ...

  5. 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 ...

  6. java中XMLGregorianCalendar类型和Date类型之间的相互转换

    import java.text.SimpleDateFormat;import java.util.Date;import java.util.GregorianCalendar;import ja ...

  7. 关于java同步包中ConcurrentLinkedQueue类的深入分析与理解

    一,官方描写叙述 一个基于连接节点的无界线程安全队列.这个队列的顺序是先进先出.队列头部的元素是留在队列中时间最长的,队列尾部的元素是留在队列中时间最短的.新元素被插入到元素的尾部,队列从队列的头部检 ...

  8. MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景

    MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...

  9. js中Boolean类型和Number类型的一些常见方法

    Boolean类型 Boolean类型重写了valueOf() 方法, 返回基本布尔类型值true或false,重写了toString() 方法,返回基本字符串"true" 和 & ...

随机推荐

  1. Activiti网关--包含网关

    1.什么是包含网关 包含网关可以看做是排他网关和并行网关的结合体:和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们:但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样,包 ...

  2. C 苟富贵

    时间限制 : 15000 MS   空间限制 : 524288 KB 问题描述 你最近买六合彩赚了很多钱,导致一个银行账户存不下了,于是你开设了 N 个账户,第 i 个账户里存有 Ai 元. 你的好友 ...

  3. Maximum splitting

    Maximum splitting You are given several queries. In the i-th query you are given a single positive i ...

  4. 人生苦短,学用python

    1. 我为什么开始学着用 python 啦?   扯扯网上疯传的一组图片.网上流传<人工智能实验教材>的图片,为幼儿园的小朋友们量身打造的实验教材,可谓是火了.甚至有网友调侃道:pytho ...

  5. 在 UITextField 中添加删除绑定(绑定删除)

    要解决的问题 在输入框中,需要整体删除诸如 “xxx@xx.com” 或 “@xxxx” 等文本 实现思路 在删除动作时,获取到当前光标的位置,如果在光标正在处在上述文本范围内,就删除一整串文本 如何 ...

  6. 1007 Maximum Subsequence Sum (25 分)

    1007 Maximum Subsequence Sum (25 分)   Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A ...

  7. Java 中为什么不能创建泛型数组?

    之前只是知道在 Java 中不能创建泛型数组,今天翻看 <Effective Java>其中对这个部分有讲解,记录一下. 现在我们假设在 Java 中可以创建泛型数组,看看可能会发生什么情 ...

  8. Pytest系列(10) - firture 传参数 request的详细使用

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 为了提高复用性,我们在写测试 ...

  9. 谈谈CSS3中display属性的Flex布局(弹性布局)

    最近为了微信小程序,回忆起之前有接触过的弹性布局(display:Flex) 网上摘录的原文地址:https://www.cnblogs.com/xuyuntao/articles/6391728.h ...

  10. node+express+mysql实现简单的数据增删改查

    前提 电脑已经安装了node,express,mysql. 实现步骤 1.新建数据库表 附数据表结构: 2.创建exprss项目 express -e myapp  新建一个以ejs为模板的expre ...