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

相关文章
|
21天前
|
存储 Java API
Java——Stream流详解
Stream流是JDK 8引入的概念,用于高效处理集合或数组数据。其API支持声明式编程,操作分为中间操作和终端操作。中间操作包括过滤、映射、排序等,可链式调用;终端操作则完成数据处理,如遍历、收集等。Stream流简化了集合与数组的操作,提升了代码的简洁性
42 11
Java——Stream流详解
|
16天前
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
31 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
8天前
|
存储 安全 Java
Java 数据结构类型总结
在 Java 中,常用的数据结构包括基础数据结构(如数组和字符串)、集合框架(如 Set、List 和 Map 接口的多种实现)、特殊数据结构(如栈、队列和双端队列)、链表(单链表、双链表和循环链表)以及图和树等。这些数据结构各有特点和适用场景,选择时需考虑性能、内存和操作需求。集合框架提供了丰富的接口和类,便于处理对象集合。
|
1月前
|
Java API C++
Java 8 Stream Api 中的 peek 操作
本文介绍了Java中`Stream`的`peek`操作,该操作通过`Consumer&lt;T&gt;`函数消费流中的每个元素,但不改变元素类型。文章详细解释了`Consumer&lt;T&gt;`接口及其使用场景,并通过示例代码展示了`peek`操作的应用。此外,还对比了`peek`与`map`的区别,帮助读者更好地理解这两种操作的不同用途。作者为码农小胖哥,原文发布于稀土掘金。
Java 8 Stream Api 中的 peek 操作
|
1月前
|
Java C# Swift
Java Stream中peek和map不为人知的秘密
本文通过一个Java Stream中的示例,探讨了`peek`方法在流式处理中的应用及其潜在问题。首先介绍了`peek`的基本定义与使用,并通过代码展示了其如何在流中对每个元素进行操作而不返回结果。接着讨论了`peek`作为中间操作的懒执行特性,强调了如果没有终端操作则不会执行的问题。文章指出,在某些情况下使用`peek`可能比`map`更简洁,但也需注意其懒执行带来的影响。
Java Stream中peek和map不为人知的秘密
|
20天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
16天前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的探索
【9月更文挑战第24天】本文将深入浅出地介绍Java 8中的重要新特性——Lambda表达式和Stream API,通过实例解析其语法、用法及背后的设计哲学。我们将一探究竟,看看这些新特性如何让Java代码变得更加简洁、易读且富有表现力,同时提升程序的性能和开发效率。
|
14天前
|
SQL Java Linux
Java 8 API添加了一个新的抽象称为流Stream
Java 8 API添加了一个新的抽象称为流Stream
|
16天前
|
Java
java基础(10)数据类型中的整数类型
Java中的整数类型包括byte、short、int和long。整数字面值默认为int类型,加L表示long类型。整数字面值可以是十进制、八进制(0开头)或十六进制(0x开头)。小容量类型(如int)可自动转换为大容量类型(如long),但大容量转小容量需强制转换,可能导致精度损失。
27 2
|
18天前
|
Java 大数据 API
Java8的stream里的并行度如何使用?效率有提升吗?
Java8的stream里的并行度如何使用?效率有提升吗?
15 4