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

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

(0)

相关推荐

  • Java InputStream的多种使用详解

    以前写东西,尤其是网络传输方面总会碰到将某种格式的文本或者图片等转幻成数据流的方式来传输,那时候用的就直接网上找点就粘贴,也没什么搞懂到底是怎么个机理.后来抽点空就死啃了点这方面的文章,稍微懂了点,特意分享一下. InputStream  FileInputStream BufferInputStream  InputStreamreader ByteArrayInputStream这些东西到底什么关系呢? 一.首先我先理解InputStream是老大,剩下的这些都是为其服务的,先建立一个标准,

  • java8 stream自定义分组求和并排序的实现

    本文主要介绍了java8 stream自定义分组求和并排序的实现,分享给大家,具体如下: public static void main(String[] args) { List<GroupDetailDTO> list = new ArrayList<>(); GroupDetailDTO dto1 = new GroupDetailDTO(); dto1.setHeadsetId(1); dto1.setTime("2020-01-03"); dto1.s

  • Java 8 Stream Api 中的 map和 flatMap 操作方法

    1.前言 Java 8提供了非常好用的 Stream API ,可以很方便的操作集合.今天我们来探讨两个 Stream中间操作 map(Function<? super T, ? extends R> mapper) 和 flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) 2. map 操作 map 操作是将流中的元素进行再次加工形成一个新流.这在开发中很有用.比如我们有一个学生集合,我们

  • 详解Java8新特性Stream之list转map及问题解决

    List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap 具体用法实例如下: //声明一个List集合 List<Person> list = new ArrayList(); list.add(new Person("1001", "小A")); list.add(new Person("1002", "小B")); list.add(new Person

  • Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)

    通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作. 注:如果对Java8新特性中的lambda表达式与Stream不熟悉的可以去补一下基础,了解概念. 首先下面代码中的List放入了很多Person对象,其中有的对象是null的,如果不加校验调用Person的getXXX()方法肯定会报空指针错误,一般我们采取的方案就是加上if判断: public class DemoUtils { public static void main(

  • java8 stream的分组功能实例介绍

    前言 最近,项目开发时遇到一个问题.根据业务要求,前端给后端上送的参数是一个列表(如List list),因此,后端也用了一个列表来接收.然而,等后端拿到数据后,我发现我需要对相同classId的数据进行统一处理.于是,我找到前端妹妹讨论,看她能不能帮忙把相同classId的数据封装成列表传给我.我好将接收参数修改成以下格式(List list): class Dto{ String classId; List<Student> list; } 这时,前端妹妹评估了下改动程度,眼泪汪汪地看着我

  • JAVA8 STREAM COLLECT GROUPBY分组实例解析

    这篇文章主要介绍了JAVA8 STREAM COLLECT GROUPBY分组实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 实体类People,有个返回list的buildPeopleList方法,方便测试. import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; impo

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

    简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢? 我们看一个peek的例子: Stream<String> stream = Stream.of("one", "two", "three","four"); stream.peek(System.out::println); 上面的例子中,我们的本意是打印出Stream的值,但实际上没有任何输出. 为什么呢? 中间

  • java开发WMS仓库商品预警需求示例解析

    目录 1.预警需求 1. 预警需求分析 2.后端代码实现: 1. 定时器任务 2.优化加入队列 3.注意:关于Mq 4.测试是否成功 3.前端提一嘴 前端展示: 1.预警需求 为了更好的管理商品日期,需要对仓库的商品进行预警管理,对商品的保质期控制在一个范围内提示出来,也可以通过该功能间接的展示出一个商品的的销量程度和对下次进货做个考量! 1. 预警需求分析 前端界面需要设置商品的预警天数 后端保存预警天数 数据库有字段存放商品需要预警的天数 通过定时器运行指点方法算出对应那些商品的批次存低于设

  • Java 在PDF中添加骑缝章示例解析

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java (免费版) 工具获取及jar文件导入: 方式1:通过官网下载jar包,并解压,手动导入lib文件夹下的Spire.Pdf.jar文件. 方式2:通过创建Maven程序,在pom.xml中配置maven仓库路径并指定Free Spire.PDF for Java 的依赖,配置完成后,在IDEA中,点击

  • JS前端操作 Cookie源码示例解析

    目录 引言 源码分析 使用 源码 分析 set get remove withAttributes & withConverter 总结 引言 前端操作Cookie的场景其实并不多见,Cookie也因为各种问题被逐渐淘汰,但是我们不用Cookie也可以学习一下它的思想,或者通过这次的源码来学习其他的一些知识. 今天带来的是:js-cookie 源码分析 使用 根据README,我们可以看到js-cookie的使用方式: // 设置 Cookies.set('name', 'value'); //

  • go语言方法集为类型添加方法示例解析

    目录 1概述 2为类型添加方法 2.1基础类型作为接收者 2.2结构体作为接收者 3值语义和引用语义 4方法集 4.1类型 *T 方法集 4.2类型 T 方法集 5匿名字段 5.1方法的继承 5.2方法的重写 6方法值和方法表达式 6.1方法值 6.2方法表达式 1概述 在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法(method).本质上,一个方法则是一个和特殊类型关联的函数. 一个面向对象的程序会用方法来表达其属性

  • java基础理论Stream管道流Map操作示例

    目录 一.回顾Stream管道流map的基础用法 二.处理非字符串类型集合元素 三.再复杂一点:处理对象数据格式转换 四.flatMap 一.回顾Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur"); //不使用Stream管道流 L

  • java理论基础Stream API终端操作示例解析

    目录 一.JavaStream管道数据处理操作 二.ForEach和ForEachOrdered 三.元素的收集collect 3.1.收集为Set 3.2.收集到List 3.3.通用的收集方式 3.4.收集到Array 3.5.收集到Map 3.6.分组收集groupingBy 四.其他常用方法 一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之

  • Java实现判断浏览器版本与类型简单代码示例

    简单的Java获取浏览器版本和类型方法,不是很完美,但是可以用: 希望大家加以完善! public static void main(String[] args) { String agent=request.getHeader("User-Agent").toLowerCase(); System.out.println(agent); System.out.println("浏览器版本:"+getBrowserName(agent)); } public Str

  • Java 8 Stream.distinct() 列表去重的操作

    在这篇文章里,我们将提供Java8 Stream distinct()示例. distinct()返回由该流的不同元素组成的流.distinct()是Stream接口的方法. distinct()使用hashCode()和equals()方法来获取不同的元素.因此,我们的类必须实现hashCode()和equals()方法. 如果distinct()正在处理有序流,那么对于重复元素,将保留以遭遇顺序首先出现的元素,并且以这种方式选择不同元素是稳定的. 在无序流的情况下,不同元素的选择不一定是稳定

  • java理论基础Stream性能论证测试示例

    目录 一.粉丝的反馈 二.所有性能测试结论都是片面的 三.动手测试Stream的性能 3.1.环境 3.2.测试用例与测试结论 3.2.1.测试用例一 3.2.2测试用例二 3.2.3测试用例三 四.最终测试结论 五.测试代码 测试用例一: 测试用例二: 测试用例三: 一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位粉丝说的这篇文章我也看过,我就

随机推荐