面试题答案
一键面试并行流和顺序流中间操作执行过程的不同
- 顺序流:
- 顺序流的中间操作是按照元素在Stream中的顺序依次执行的。例如,先执行
filter
操作,一个元素接一个元素地判断是否满足过滤条件,只有满足条件的元素才会进入后续的map
等操作。每个元素的处理是顺序进行的,前一个元素处理完后才处理下一个元素。
- 顺序流的中间操作是按照元素在Stream中的顺序依次执行的。例如,先执行
- 并行流:
- 并行流会将流中的元素分成多个部分,然后使用多个线程并行地处理这些部分。对于
filter
操作,不同的线程会同时处理不同部分的元素进行过滤。但是,由于并行处理,元素的处理顺序是不确定的。而且,在并行流中,为了保证结果的正确性,一些中间操作可能需要额外的协调和合并步骤,比如在进行map
操作后,需要将各个线程处理的结果合并起来。
- 并行流会将流中的元素分成多个部分,然后使用多个线程并行地处理这些部分。对于
代码验证
以下是使用Java 8 Stream API进行验证的代码示例:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class CustomObject {
private int id;
public CustomObject(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
public class StreamExecutionExample {
public static void main(String[] args) {
List<CustomObject> customObjectList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
customObjectList.add(new CustomObject(i));
}
// 顺序流
System.out.println("顺序流:");
customObjectList.stream()
.filter(obj -> {
System.out.println("顺序流过滤: " + obj.getId());
return obj.getId() % 2 == 0;
})
.map(obj -> {
System.out.println("顺序流映射: " + obj.getId());
return obj.getId() * 2;
})
.findFirst()
.ifPresent(System.out::println);
// 并行流
System.out.println("\n并行流:");
customObjectList.parallelStream()
.filter(obj -> {
System.out.println("并行流过滤: " + obj.getId());
return obj.getId() % 2 == 0;
})
.map(obj -> {
System.out.println("并行流映射: " + obj.getId());
return obj.getId() * 2;
})
.findFirst()
.ifPresent(System.out::println);
}
}
在上述代码中,我们创建了一个包含CustomObject
的列表,并分别对其顺序流和并行流进行filter
和map
操作,同时在每个中间操作中打印日志,观察执行顺序。顺序流中日志打印的顺序和元素顺序一致,而并行流中日志打印顺序混乱,体现了并行处理的特性。