Java8 关于stream.foreach()和stream.peek()的区别解析
该思考来源于日常工作中,特记此心得。
思考:如何快速将list中的每个item内部属性值改变并进行其他流体操作呢?
下面做个测试:如何先在list中统一改变某属性的值,然后再根据某个属性取出该属性值最小的对象
1:随便新建一个测试bean:


- 1 package com.dev.model;
- 2
- 3 import javax.persistence.*;
- 4
- 5 public class Aopi {
- 6 /**
- 7 * id
- 8 */
- 9 @Id
- 10 @GeneratedValue(strategy = GenerationType.IDENTITY)
- 11 private Integer id;
- 12
- 13 /**
- 14 * 姓名
- 15 */
- 16 private String name;
- 17
- 18 /**
- 19 * 年龄
- 20 */
- 21 private Integer age;
- 22
- 23 /**
- 24 * 获取id
- 25 *
- 26 * @return id - id
- 27 */
- 28 public Integer getId() {
- 29 return id;
- 30 }
- 31
- 32 /**
- 33 * 设置id
- 34 *
- 35 * @param id id
- 36 */
- 37 public void setId(Integer id) {
- 38 this.id = id;
- 39 }
- 40
- 41 /**
- 42 * 获取姓名
- 43 *
- 44 * @return name - 姓名
- 45 */
- 46 public String getName() {
- 47 return name;
- 48 }
- 49
- 50 /**
- 51 * 设置姓名
- 52 *
- 53 * @param name 姓名
- 54 */
- 55 public void setName(String name) {
- 56 this.name = name;
- 57 }
- 58
- 59 /**
- 60 * 获取年龄
- 61 *
- 62 * @return age - 年龄
- 63 */
- 64 public Integer getAge() {
- 65 return age;
- 66 }
- 67
- 68 /**
- 69 * 设置年龄
- 70 *
- 71 * @param age 年龄
- 72 */
- 73 public void setAge(Integer age) {
- 74 this.age = age;
- 75 }
- 76
- 77 public Aopi(String name, Integer age) {
- 78 this.name = name;
- 79 this.age = age;
- 80 }
- 81
- 82 public Aopi() {
- 83 }
- 84
- 85 @Override
- 86 public String toString() {
- 87 return "Aopi{" +
- 88 "id=" + id +
- 89 ", name='" + name + '\'' +
- 90 ", age=" + age +
- 91 '}';
- 92 }
- 93 }
2:新建一个单元测试:
- @Test
- public void test01() {
- List<Aopi> aopiList = Lists.newArrayList();
- Aopi aopi = new Aopi("1", 1);
- Aopi aop2 = new Aopi("2", 2);
- Aopi aop3 = new Aopi("3", 3);
- Aopi aop4 = new Aopi("4", 4);
- aopiList.addAll(Arrays.asList(aopi, aop2, aop3, aop4));
- //第一种方式
- aopiList.forEach(item -> item.setName(item.getName() + "_test"));
- System.out.println(
- aopiList.stream().min((o1, o2) -> {
- if (Objects.equals(o1.getAge(), o2.getAge()))
- return 0;
- return o1.getAge() > o2.getAge() ? 1 : -1;
- }).get().toString()
- );
- System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
- //第二种方式
- System.out.println(
- aopiList.stream().peek(item -> item.setName(item.getName() + "_test")).min((o1, o2) -> {
- if (Objects.equals(o1.getAge(), o2.getAge()))
- return 0;
- return o1.getAge() > o2.getAge() ? 1 : -1;
- }).get().toString()
- );
- }
notice1:测试第一种方式注释掉第二种,反之亦如此
notice2:list.stream().foreach -> list.foreach()
3:看测试结果:
第一种测试结果:
第二种测试结果:
结论:
(1):使用stream.foreach也可以更改list中的每个item的内部属性值等等,但是要进行“二次流处理”,才能得到list中最小的item(根据age筛选)
(2):stream.peek比stream.foreach()可以跟直接拿到最小的item(根据age筛选)
原因:
(1):stream.foreach的操作是void的,除了更改属性值还可以进行其他操作等。因此要做“二次流处理”。
- default void forEach(Consumer<? super T> action) {
- Objects.requireNonNull(action);
- for (T t : this) {
- action.accept(t);
- }
- }
(1):stream.peek的操作是返回一个新的stream的,且设计的初衷是用来debug调试的,因此使用steam.peek()必须对流进行一次处理再产生一个新的stream。
- /**
- * Returns a stream consisting of the elements of this stream, additionally
- * performing the provided action on each element as elements are consumed
- * from the resulting stream.
- *
- * <p>This is an <a href="package-summary.html#StreamOps">intermediate
- * operation</a>.
- *
- * <p>For parallel stream pipelines, the action may be called at
- * whatever time and in whatever thread the element is made available by the
- * upstream operation. If the action modifies shared state,
- * it is responsible for providing the required synchronization.
- *
- * @apiNote This method exists mainly to support debugging, where you want
- * to see the elements as they flow past a certain point in a pipeline:
- * <pre>{@code
- * 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());
- * }</pre>
- *
- * @param action a <a href="package-summary.html#NonInterference">
- * non-interfering</a> action to perform on the elements as
- * they are consumed from the stream
- * @return the new stream
- */
- Stream<T> peek(Consumer<? super T> action);
Java8 关于stream.foreach()和stream.peek()的区别解析的更多相关文章
- [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路
Stream的概念定义 官方文档是永远的圣经~ 表格内容来自https://docs.oracle.com/javase/8/docs/api/ Package java.util.s ...
- java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比
java8 for ,forEach ,Iterator,lambda forEach ,lambda strean forEach , lambda parller stream forEach性 ...
- Java 8 Stream Api 中的 peek 操作
1. 前言 我在Java8 Stream API 详细使用指南[1] 中讲述了 [Java 8 Stream API]( "Java 8 Stream API") 中 map 操作 ...
- 十分钟学会Java8的lambda表达式和Stream API
01:前言一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏 ...
- Java8新特性之三:Stream API
Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式.Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找.过滤.筛选等操作 ...
- java8中Lambda表达式和Stream API
一.Lambda表达式 1.语法格式 Lambda是匿名函数,可以传递代码.使用“->”操作符,改操作符将lambda分成两部分: 左侧:指定了 Lambda 表达式需要的所有参数 右侧:指定了 ...
- 十分钟学会Java8:lambda表达式和Stream API
Java8 的新特性:Lambda表达式.强大的 Stream API.全新时间日期 API.ConcurrentHashMap.MetaSpace.总得来说,Java8 的新特性使 Java 的运行 ...
- Java8中的 lambda 和Stream API
前言 由于项目中用到了比较多有关于 Java8 中新的东西,一开始自己只是会写,但是写起来不太顺,然后就在网上找到了一个很好的关于Java8新特性的视频,所以就进行了学习了一下,以下是自己对 la ...
- Java8的lambda表达式和Stream API
一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏味,非过来 ...
随机推荐
- Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) C. Remove Adjacent(字符串,贪心,枚举)
题意: 给你一个由小写字母组成的字符串,若串中两个相邻元素字典序中也相邻,移除较大字母,问最多能移除多少个字母. 思路: 从大到小依次枚举. Tips: 注意下标的处理. 以小消大: #include ...
- hdu4028 The time of a day (map+dp)
Problem Description There are no days and nights on byte island, so the residents here can hardly de ...
- hdu5402 Travelling Salesman Problem
Problem Description Teacher Mai is in a maze with n rows and m columns. There is a non-negative numb ...
- Pollard_rho算法进行质因素分解
Pollard_rho算法进行质因素分解要依赖于Miller_Rabbin算法判断大素数,没有学过的可以看一下,也可以当成模板来用 讲一下Pollard_rho算法思想: 求n的质因子的基本过程是,先 ...
- Codeforces Round #651 (Div. 2) C. Number Game (博弈,数学)
题意:对于正整数\(n\),每次可以选择使它变为\(n-1\)或者\(n/t\) (\(n\ mod\ t=0\)且\(t\)为奇数),当\(n=1\)时便不可以再取,问先手赢还是后手赢. 题解:首先 ...
- C++ 结构体 segment fault
形如 struct node { int key; int height; int size; //tree node 个数 node *left, *right; node(int x) : key ...
- PAT l2-010 排座位 【并查集】
L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位. ...
- HTTP1.0和HTTP1.1以及HTTP2.0的区别
(1)连接方面 HTTP1.0使用非持久连接,即在非持久连接下,一个tcp连接只传输一个Web对象.每次请求和响应都需要建立一个单独的连接,每次连接只是传输一个对象,严重影响客户机和服务器的性能. H ...
- USB2.0协议学习笔记---基本概念
概念 USB是一种串行通信总线(Universal Serial Bus),经历的版本有USB1.0,USB1.1.USB2.0等.USB是一种主从模式的结构,因此它无法在设备与设备.主机与主机之间 ...
- 将从摄像头即时读入的人像放入背景视频中_with_OpenCV_in_Python
import cv2 import numpy as np import time cap = cv2.VideoCapture(0) background_capture = cv2.VideoCa ...