对 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)
相关文章
|
6天前
|
存储
`map()`方法在什么场景下会比 `forEach()`方法更高效?
综上所述,当需要对数组元素进行复杂的转换并生成新数组、进行链式调用和函数式编程、处理元素之间存在明确映射关系的情况以及与其他数组方法结合使用时,`map()`方法比`forEach()`方法更高效,能够使代码更加简洁、清晰和易于维护。
45 32
|
6天前
|
存储 JavaScript 前端开发
如何选择使用`map()`方法和`forEach()`方法?
选择使用`map()`方法还是`forEach()`方法主要取决于操作的目的、是否需要返回值、代码的可读性和维护性等因素。在实际开发中,需要根据具体的业务需求和场景来灵活选择合适的方法,以实现更高效、更易读和更易维护的代码。
13 3
|
2月前
|
索引
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
|
2月前
|
Java C# Swift
Java Stream中peek和map不为人知的秘密
本文通过一个Java Stream中的示例,探讨了`peek`方法在流式处理中的应用及其潜在问题。首先介绍了`peek`的基本定义与使用,并通过代码展示了其如何在流中对每个元素进行操作而不返回结果。接着讨论了`peek`作为中间操作的懒执行特性,强调了如果没有终端操作则不会执行的问题。文章指出,在某些情况下使用`peek`可能比`map`更简洁,但也需注意其懒执行带来的影响。
139 2
Java Stream中peek和map不为人知的秘密
|
2月前
|
存储 JavaScript 前端开发
`forEach()`方法和`map()`方法哪个执行效率更高?
`forEach()`方法和`map()`方法哪个执行效率更高?
|
1月前
|
存储 分布式计算 Java
Stream很好,Map很酷,但答应我别用toMap():Java开发中的高效集合操作
在Java的世界里,Stream API和Map集合无疑是两大强大的工具,它们极大地简化了数据处理和集合操作的复杂度。然而,在享受这些便利的同时,我们也应当警惕一些潜在的陷阱,尤其是当Stream与Map结合使用时。本文将深入探讨Stream与Map的优雅用法,并特别指出在使用toMap()方法时需要注意的问题,旨在帮助大家在工作中更高效、更安全地使用这些技术。
41 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 高效处理数据