Stream.peek

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

生成一个新的流,该流中的元素由当前流的元素组成,新流中每个元素都绑定一个操作,当新流中的元素被使用或被消费的时候该操作被触发执行。

看一个例子:

void stream_peek() {

        Stream.of("Mr.zhangsan","Mr.lisi","Mr.wanger","Mr.mazi")

        .filter(a -> a.length()>7)

        .peek(b -> System.out.println("Name: "+b))

        .collect(Collectors.toList());

       

    }

运行结果:

Name: Mr.zhangsan

Name: Mr.wanger

 

再看一个例子,这个例子中我们使用peek来修改User对象中的数据:

List<User> users = List.of(new User("111@qq.com","beijing"), new User("222@qq.com","shanghai"), new User("333@qq.com","tianjin"));

        users.stream().peek(a -> {System.out.println(a.toString());a.setAddr("china - "+a.getAddr());}).forEach(System.out::println);

运行结果:

User [email=111@qq.com, addr=beijing, age=0]

User [email=111@qq.com, addr=china - beijing, age=0]

User [email=222@qq.com, addr=shanghai, age=0]

User [email=222@qq.com, addr=china - shanghai, age=0]

User [email=333@qq.com, addr=tianjin, age=0]

User [email=333@qq.com, addr=china - tianjin, age=0]

 

下面看看官方文档中的一个示例:

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

 

这个例子绑定操作打印新流中的数据这块没有什么可以说的,但是注意到打印元素的顺序,因为最终消费流元素的方法是collect方法,该方法执行过程大概如下:先new一个空的ArrayList,然后使用该类的add方法逐个把元素添加到ArrayList中,因此当add第一个元素three的时候分别触发绑定在filer方法和map方法生成的新的流上的打印操作,因此这个时候打印一个小写three和一个大写THREE,然后再add第二个元素的时候也和第一个元素一样,因此出现上面例子的运行结果。

 

我们把上面代码最终消费流元素的方法修改一下,然后看看运行结果:

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))

        .allMatch(a -> a.length()==4);

运行结果:

Filtered value: three

Mapped value: THREE

 

看到没有只打印了大小写的three,为什么呢?因为allMacth方法只消费了第一个元素,而没有消费第二个元素,因此只触发第一个元素绑定的两个打印操作。我们执行回顾一下allMacth方法的执行顺序,就以上面例子代码来分析,流中有两个元素分别是“threee”和“four”,allMacth方法中参数函数定义的判断条件是元素字符串长度为4,那就是说要流中全部元素长度都要等于4,有一个不等于就直接中断操作返回false,那我们按顺序分别取流中两个元素进行判断,第一个元素是“three”,长度为5,不等于4,好了,第一个就不满足条件,那后面也没有必要继续判断下去了,直接返回false结果,这就是为什么只打印了大小写的“three”,而没有打印大小写的“four”。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
stream.peek方法的作用是在流的每个元素上执行指定的操作,在不修改流中元素的情况下返回一个新的流。它接受一个Consumer类型的参数,该参数指定了要执行的操作。在中间操作中使用peek方法可以方便地对流进行调试,了解每个操作之前和操作之后的中间值。 在引用的代码中,虽然调用了stream.peek(System.out::println),但没有任何输出。这是因为peek方法是一个中间操作,它只会在终止操作被调用时才会执行。在代码中,并没有调用任何终止操作,所以没有输出。如果想要输出流中的值,可以在peek方法后添加一个终止操作,例如forEach方法来打印出流中的元素。 下面是修改后的代码示例: ```java 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).forEach(System.out::println); } } ``` 现在,当运行这段代码时,会先输出每个元素的值,然后再打印出流中的元素值。这是因为在peek方法中,我们指定了打印每个元素的操作,而在forEach方法中,我们又指定了打印流中元素的操作。这样就能够看到每个操作之前和操作之后的中间值。 请注意,peek方法不会改变流中的元素,它只是提供了一种便捷的方式来查看流中每个元素的值。要改变流中的元素,需要使用其他的中间操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值