對 Stream 中 Map 與 ForEach 做個簡單說明

經常會有童鞋把 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章