Stream中的Peek操作代码

 更新时间:2023年09月26日 10:07:35   作者:自律的西瓜L  
这篇文章主要介绍了Stream中的Peek操作,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

peek()是一个Intermediate操作,它接收一个Consumer类型的lambda参数(void类型),对每个元素执行操作并返回一个新的Stream,并可以继续进行流的操作。peek()方法不会影响原始流中的元素。

1.引言

       如果你试图对流操作中的流水线进行调试, 了解stream流水线每个操作之前和操作之后的中间值, 该如何去做?

       首先我们看一个例子, 使用forEach将流操作的结果打印出来.

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekTestOne {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(4, 7, 9, 11, 12);
        list.stream()
                .map(x -> x + 2)
                .filter(x -> x % 2 != 0)
                .limit(2)
                .forEach(System.out::println);
    }
}
输出结果如下:
9
11

       可以很明显的看出, 一旦调用了forEach操作, 整个流就会恢复运行.并不能很好的帮助我们了解Stream流水线中的每个操作(如:map,filter,limit等)产生的输出.

       再来看一个例子

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekTestTwo {
    public static void main(String[] args) {
        Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream();
        stream.peek(System.out::println);
    }
}
这段代码是想打印stream中的值,却没有任何输出.

2.中间操作和终止操作

       中间操作是流水线中的数据进行加工的, 它是一个懒操作, 并不会马上执行, 需要等待有终止操作的时候才会执行.

       终止操作是Stream的启动操作, 当有终止操作的时候, Stream才会真正的开始执行.

       因此, 这里可以解释上面的peek操作是一个中间操作, 所以没有任何输出.

3.使用peek进行debug操作

       peek的设计初衷就是在流的每个元素恢复运行之前的时候插入一个执行操作. 它不想forEach那样恢复整个流的运行操作. 而是在一个元素上完成操作之后, 它只会将操作顺承到流水线的下一个操作. 它能够将中间变量的值输出到日志. 有效的帮助我们了解流水线的每一步操作的输出值.如下图:

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekTestThree {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(4, 7, 9, 11, 12);
        list.stream()
                .peek(x -> System.out.println("stream: " + x))
                .map(x -> x + 2)
                .peek(x -> System.out.println("map: " + x))
                .filter(x -> x % 2 != 0)
                .peek(x -> System.out.println("filter: " + x))
                .limit(2)
                .peek(x -> System.out.println("limit: " + x))
                .collect(toList());
    }
}
输出结果如下:
stream: 4
map: 6
stream: 7
map: 9
filter: 9
limit: 9
stream: 9
map: 11
filter: 11
limit: 11
Process finished with exit code 0

4.peek和map的区别

  使用peek操作流,流中的元素没有改变。

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekAndMapTestOne {
    public static void main(String[] args) {
        Arrays.asList("a","b")
                .stream()
                .peek(x -> x.toUpperCase())
                .forEach(System.out::println);
    }
}
输出:
a
b
Process finished with exit code 0

  使用map操作流,流中的元素有改变。

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekAndMapTestTwo {
    public static void main(String[] args) {
        Arrays.asList("a","b")
                .stream()
                .map(x -> x.toUpperCase())
                .forEach(System.out::println);
    }
}
输出:
A
B
Process finished with exit code 0

  可以通过上面两个例子看出,map操作是对元素进行了转换。

  注意:peek对一个对象进行操作的时候,对象不变,但是可以改变对象里面的值.如下:

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
@Getter
@Setter
@AllArgsConstructor
@ToString
public class Person {
    private String id;
    private String name;
}
----------------------------------------------------------------------------
/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/5/28
 */
public class PeekAndMapTestThree {
    public static void main(String[] args) {
        Arrays.asList(new Person("001","zs"),new Person("002","ls"))
                .stream().peek(p -> p.setId("000")).forEach(System.out::println);
    }
}
输出:
Person(id=000, name=zs)
Person(id=000, name=ls)
Process finished with exit code 0

  peek的定义

Stream<T> peek(Consumer<? super T> action);

        peek方法接收一个Consumer的入参. 了解λ表达式的应该明白 Consumer的实现类应该只有一个方法,该方法返回类型为void. 它只是对Stream中的元素进行某些操作,但是操作之后的数据并不返回到Stream中,所以Stream中的元素还是原来的元素.

  map的定义

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

  map方法接收一个Function作为入参. Function是有返回值的, 这就表示map对Stream中的元素的操作结果都会返回到Stream中去.

到此这篇关于Stream中的Peek操作的文章就介绍到这了,更多相关Stream Peek操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Eclipse远程debug的步骤与注意事项

    Eclipse远程debug的步骤与注意事项

    今天小编就为大家分享一篇关于Eclipse远程debug的步骤与注意事项,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 关于synchronized有趣的同步问题

    关于synchronized有趣的同步问题

    今天小编就为大家分享一篇关于关于synchronized有趣的同步问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • MultipartFile文件判断是否存在的操作

    MultipartFile文件判断是否存在的操作

    这篇文章主要介绍了MultipartFile文件判断是否存在的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • logback ThresholdFilter临界值日志过滤器源码解读

    logback ThresholdFilter临界值日志过滤器源码解读

    这篇文章主要为大家介绍了logback ThresholdFilter临界值日志过滤器源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java Integer.valueOf()和Integer.parseInt()的区别说明

    Java Integer.valueOf()和Integer.parseInt()的区别说明

    这篇文章主要介绍了Java Integer.valueOf()和Integer.parseInt()的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java后端进行跨域的几种方式小结

    java后端进行跨域的几种方式小结

    本文主要介绍了java后端进行跨域的几种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Springboot集成Actuator监控功能详解

    Springboot集成Actuator监控功能详解

    这篇文章主要介绍了Springboot集成Actuator监控功能详解,有时候我们想要实时监控我们的应用程序的运行状态,比如实时显示一些指标数据,观察每时每刻访问的流量,或者是我们数据库的访问状态等等,这时候就需要Actuator了,需要的朋友可以参考下
    2023-09-09
  • Java实现的微信公众号获取微信用户信息示例

    Java实现的微信公众号获取微信用户信息示例

    这篇文章主要介绍了Java实现的微信公众号获取微信用户信息,结合实例形式分析了Java微信公众号获取微信用户信息相关原理、步骤与操作注意事项,需要的朋友可以参考下
    2019-10-10
  • gRPC在Java中的实现与应用详解

    gRPC在Java中的实现与应用详解

    gRPC是由Google开发的高性能、开源的通用远程过程调用(RPC)框架,本文将详细介绍如何在Java中使用gRPC,包括服务定义、服务器端实现、客户端调用以及一些高级特性,我们将通过代码示例来帮助理解gRPC的工作原理,需要的朋友可以参考下
    2024-06-06
  • 带你入门java雪花算法原理

    带你入门java雪花算法原理

    SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的
    2021-06-06

最新评论