我一直试图从官方Java文档中找到明确的合同,关于Java流的顺序,一旦调用终端操作,就处理元素并调用中间操作.
例如,让我们看看这些使用Java流版本和普通迭代版本的示例(两者都产生相同的结果).
例1:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5);
Function<Integer, Integer> map1 = i -> i;
Predicate<Integer> f1 = i -> i > 2;
public int findFirstUsingStreams(List<Integer> ints){
return ints.stream().map(map1).filter(f1).findFirst().orElse(-1);
}
public int findFirstUsingLoopV1(List<Integer> ints){
for (int i : ints){
int mappedI = map1.apply(i);
if ( f1.test(mappedI) ) return mappedI;
}
return -1;
}
public int findFirstUsingLoopV2(List<Integer> ints){
List<Integer> mappedInts = new ArrayList<>( ints.size() );
for (int i : ints){
int mappedI = map1.apply(i);
mappedInts.add(mappedI);
} …Run Code Online (Sandbox Code Playgroud) 是否可以保证在使用流时,中间操作将按程序顺序执行?我怀疑是这种情况,或者它会导致非常微妙的错误,但我找不到明确的答案.
例:
List<String> list = Arrays.asList("a", "b", "c");
List<String> modified = list.parallelStream()
.map(s -> s + "-" + s) //"a-a", "b-b", "c-c"
.filter(s -> !s.equals("b-b")) //"a-a", "c-c"
.map(s -> s.substring(2)) //"a", "c"
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
这保证总是返回["a", "c"]或["c", "a"]?(如果最后一个映射操作在第一个映射操作之前执行,则可能抛出异常 - 类似地,如果在第二个映射操作之后执行过滤器,则"b"将保留在最终列表中)