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,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏味,非过来 ...
随机推荐
- 「SCOI2005」互不侵犯 (状压DP)
题目链接 在\(N\times N\) 的棋盘里面放 \(K\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共\(8\) 个格子 ...
- Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) C. Remove Adjacent(字符串,贪心,枚举)
题意: 给你一个由小写字母组成的字符串,若串中两个相邻元素字典序中也相邻,移除较大字母,问最多能移除多少个字母. 思路: 从大到小依次枚举. Tips: 注意下标的处理. 以小消大: #include ...
- Codeforces Round #656 (Div. 3) A. Three Pairwise Maximums (数学)
题意:给你三个正整数\(x\),\(y\),\(z\),问能够找到三个正整数\(a\),\(b\),\(c\),使得\(x=max(a,b)\),\(y=max(a,c)\),\(z=max(b,c) ...
- c#小灶——9.算术运算符
算数运算符用来在程序中进行运算. 首先,了解最简单的加(+)减(-)乘(*)除(/)运算符: 举例 int a = 1; int b = 2; int c = a + b; Console.Write ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)
JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...
- python之字符串方法upper/lower
1.描述: upper():用于将字符串全部转换为大写字母 lower():用于将字符串全部转换为小写字母 2.语法 str.upper() str.lower() 3.返回值 upper()或low ...
- 字节笔试题 leetcode 69. x 的平方根
更多精彩文章请关注公众号:TanLiuYi00 题目 解题思路 题目要求非负整数 x 的平方根,相当于求函数 y = √x 中 y 的值. 函数 y = √x 图像如下: 从上图中,可以看出函数是单 ...
- C# 类 (7) - 抽象 Abstract
Abstract 抽象类,关键字Abstract ,最典型的应用就是在 继承机制里 作为base类,抽象类是不能被实例化的(前面说的static 类也不能被实例化)它必须作为 基类,被别人继承,然后必 ...
- HDU 6704 K-th occurrence(主席树 + RMQ + 后缀数组)题解
题意: 给一个串\(S\),\(length\leq 1e5\),\(Q\leq1e5\)个询问,每次询问输出和\(S_lS_{l+1}\dots S_r\)长得一模一样的第\(k\)个子串的开头位置 ...
- vagrant + virtualbox安装centos环境+docker安装
1. 下载vagrant 并安装,安装完成后,输入vagrant回车查看是否安装成功 2. 下载virtualbox.box并安装,安装完成后. 3. 创建虚拟机文件夹,例如.F:/vmimg/fir ...