欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 8 Stream操作类型及peek示例解析

程序员文章站 2022-03-26 08:06:09
简介java 8 stream作为流式操作有两种操作类型,中间操作和终止操作。这两种有什么区别呢?我们看一个peek的例子:stream stream = stream.o...

简介

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的使用。希望大家能够掌握。

本文的例子

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。