經常會有童鞋把 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)