java 8 Stream中操作类型和peek的使用

简介: 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

相关文章
|
5月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
250 2
|
5月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
160 7
|
6月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
6月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
6月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
346 100
|
6月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
355 101
|
6月前
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
352 101
|
6月前
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
134 0
Java Stream API 的强大功能
|
7月前
|
存储 NoSQL Java
Java Stream API:集合操作与并行处理
Stream API 是 Java 8 提供的集合处理工具,通过声明式编程简化数据操作。它支持链式调用、延迟执行和并行处理,能够高效实现过滤、转换、聚合等操作,提升代码可读性和性能。
|
7月前
|
安全 算法 Java
Java泛型编程:类型安全与擦除机制
Java泛型详解:从基础语法到类型擦除机制,深入解析通配符与PECS原则,探讨运行时类型获取技巧及最佳实践,助你掌握泛型精髓,写出更安全、灵活的代码。