对 Stream 中 Map 与 ForEach 做个简单说明

简介: 经常会有童鞋把 Map 和 Foreach 用错,可能会出现如下用法: List studentChangeList = studentList.stream() .forEach(student -> student.setAge(99)); 有些编译器会直接报错,比如 IDEA。

经常会有童鞋把 Map 和 Foreach 用错,可能会出现如下用法:

List<Student> studentChangeList = studentList.stream()
        .forEach(student -> student.setAge(99));

有些编译器会直接报错,比如 IDEA。因为 ForEach 是没有返回值的,ForEach 处理过的 Stream 是无法再赋值给 studentChangeList 。

但是现在就是需要对集合进行处理,并获取处理过的集合数据,这时候可以这样做

studentList.stream().forEach(student -> student.setAge(99));

studentList 中的数据就是已经处理过的数据。

下面就 Map 和 ForEach 做一些简单的说明,大体上就能对这两个方法有所理解

一、 结论

Map:返回的是一个新流,可以对这个流进一步操作

ForEach:返回void,即无返回值

二、源码

1. Map 源码说明


    /**
     * Returns a stream consisting of the results of applying the given
     * function to the elements of this stream.
     *
     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
     * operation</a>.
     *
     * @param <R> The element type of the new stream
     * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
     *               <a href="package-summary.html#Statelessness">stateless</a>
     *               function to apply to each element
     * @return the new stream
     */
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);

2. ForEach 源码说明


    /**
     * Performs an action for each element of this stream.
     *
     * <p>This is a <a href="package-summary.html#StreamOps">terminal
     * operation</a>.
     *
     * <p>The behavior of this operation is explicitly nondeterministic.
     * For parallel stream pipelines, this operation does <em>not</em>
     * guarantee to respect the encounter order of the stream, as doing so
     * would sacrifice the benefit of parallelism.  For any given element, the
     * action may be performed at whatever time and in whatever thread the
     * library chooses.  If the action accesses shared state, it is
     * responsible for providing the required synchronization.
     *
     * @param action a <a href="package-summary.html#NonInterference">
     *               non-interfering</a> action to perform on the elements
     */
    void forEach(Consumer<? super T> action);

三、应用

1.Map 是1对1的映射

示例:
将两位同学的年龄都加上100

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        Student student1 = new Student();
        student1.setStudentId(1);
        student1.setStudentName("李毅");
        student1.setAge(17);
        Student student2 = new Student();
        student2.setStudentId(2);
        student2.setStudentName("张三丰");
        student2.setAge(18);
        studentList.add(student1);
        studentList.add(student2);
        List<Integer> ageList = studentList.stream()
                .map(student -> student.getAge() + 100)
                .collect(Collectors.toList());
        ageList.stream().forEach(System.out::println);

    }

运行结果:

117
118

2.ForEach 是对 Stream 中每一个元素进行处理。

虽然 ForEach 处理 Stream 中元素的时候没有返回值,但是 ForEach 对 Stream 中元素已经产生影响,即 ForEach 对 Stream 中元素的操作已经被保存下来。

示例:
将两位同学的年龄改为99,名字改为英俊

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        Student student1 = new Student();
        student1.setStudentId(1);
        student1.setStudentName("李毅");
        student1.setAge(17);
        Student student2 = new Student();
        student2.setStudentId(2);
        student2.setStudentName("张三丰");
        student2.setAge(18);
        studentList.add(student1);
        studentList.add(student2);
        studentList.stream().forEach(student -> {
            student.setAge(99);
            student.setStudentName("英俊");
        });
        studentList.stream().forEach(System.out::println);
    }

运行结果:

Student(studentId=1, studentName=英俊, age=99)
Student(studentId=2, studentName=英俊, age=99)
相关文章
|
2月前
|
索引
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
|
1天前
|
存储 JavaScript
foreach和map
foreach和map
7 1
|
5天前
|
存储 JavaScript
foreach和map
foreach和map
6 1
|
2月前
|
Java C# Swift
Java Stream中peek和map不为人知的秘密
本文通过一个Java Stream中的示例,探讨了`peek`方法在流式处理中的应用及其潜在问题。首先介绍了`peek`的基本定义与使用,并通过代码展示了其如何在流中对每个元素进行操作而不返回结果。接着讨论了`peek`作为中间操作的懒执行特性,强调了如果没有终端操作则不会执行的问题。文章指出,在某些情况下使用`peek`可能比`map`更简洁,但也需注意其懒执行带来的影响。
105 2
Java Stream中peek和map不为人知的秘密
|
2月前
|
存储 JavaScript 前端开发
`forEach()`方法和`map()`方法哪个执行效率更高?
`forEach()`方法和`map()`方法哪个执行效率更高?
|
27天前
|
存储 分布式计算 Java
Stream很好,Map很酷,但答应我别用toMap():Java开发中的高效集合操作
在Java的世界里,Stream API和Map集合无疑是两大强大的工具,它们极大地简化了数据处理和集合操作的复杂度。然而,在享受这些便利的同时,我们也应当警惕一些潜在的陷阱,尤其是当Stream与Map结合使用时。本文将深入探讨Stream与Map的优雅用法,并特别指出在使用toMap()方法时需要注意的问题,旨在帮助大家在工作中更高效、更安全地使用这些技术。
33 0
|
2月前
数组方法中的`forEach()`方法和`map()`方法有什么区别?
数组方法中的`forEach()`方法和`map()`方法有什么区别?
|
2月前
|
JavaScript 前端开发
JavaScript 中 五种迭代数组的方法 every some map filter forEach
本文介绍了JavaScript中五种常用数组迭代方法:every、some、filter、map和forEach,并通过示例代码展示了它们的基本用法和区别。
|
3月前
|
JavaScript 前端开发 索引
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
这段代码和说明介绍了JavaScript中数组的一些常用方法。函数接收三个参数:`item`(数组项的值)、`index`(项的位置,可选)和`array`(数组本身,可选)。示例展示了如何使用`filter()`过滤非空项、`forEach()`遍历数组、`map()`处理并返回新数组、`every()`检查所有元素是否满足条件、`some()`检查是否存在满足条件的元素、`find()`获取首个符合条件的元素值以及`findIndex()`获取其索引位置。这些方法都不会修改原数组。
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
|
3月前
|
存储 算法 Java
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据