Java 中间操作和终端操作之间有什么区别?
有人能告诉我Java 中间操作和终端操作之间有什么区别?,java,java-8,java-stream,Java,Java 8,Java Stream,有人能告诉我流的中间操作和终端操作之间的区别吗 流操作被合并到管道中以处理流。所有操作都是中间操作或终端操作。..means?终端意味着结束进程,例如将流收集到列表,或聚合值流 中间-在过渡到新状态的过程中,在执行终端操作的过程中,您可能会注意到,当您定义流时,这些方法不仅仅是对整个流逐个调用,而是对流中的每个元素执行某些操作。为了能够并行运行这些流,对于每个元素,基本上都有一个完整的管道 为了创建多个管道,Java8+使用。在每个中间步骤中,您都会向堆栈添加一个过滤器或转换器。为了告诉Java
流的中间操作和终端操作之间的区别吗
流
操作被合并到管道中以处理流。所有操作都是中间操作或终端操作。..means?终端意味着结束进程,例如将流收集到列表,或聚合值流
中间-在过渡到新状态的过程中,在执行终端操作的过程中,您可能会注意到,当您定义流时,这些方法不仅仅是对整个流逐个调用,而是对流中的每个元素执行某些操作。为了能够并行运行这些流,对于每个元素,基本上都有一个完整的管道
为了创建多个管道,Java8+使用。在每个中间步骤中,您都会向堆栈添加一个过滤器或转换器。为了告诉Java从过滤器堆栈生成管道,您使用了终止步骤。最后一步结合了所有不同的管道。通常它只返回定义格式的值,例如列表,但它也可以为每个元素运行一次函数,或将结果减少为布尔值或数字。流支持多个操作,这些操作分为中间操作和终端操作
这些操作之间的区别在于中间操作是惰性的,而终端操作不是惰性的。在流上调用中间操作时,不会立即执行该操作。它仅在对该流调用终端操作时执行。在某种程度上,中间操作被存储并在终端操作被调用时被调用。您可以链接多个中间操作,在您调用终端操作之前,它们都不会做任何事情。此时,您先前调用的所有中间操作将与终端操作一起调用
所有中间操作返回流(可以链接),而终端操作不返回流。中间业务包括:
filter(Predicate<T>)
map(Function<T>)
flatMap(Function<T>)
sorted(Comparator<T>)
peek(Consumer<T>)
distinct()
limit(long n)
skip(long n)
forEach
forEachOrdered
toArray
reduce
collect
min
max
count
anyMatch
allMatch
noneMatch
findFirst
findAny
最后5项是短路终端操作。根据:
- 中间操作将一个流转换为另一个流,例如
map(MapperFn)
或过滤器(谓词)
- 终端操作将产生结果或副作用,例如
count()
或forEach(消费者)
请注意,所有中间操作都将不执行,而在结束时不执行终端操作。因此,模式将是:
stream()
.intemediateOperation1()
.intemediateOperation2()
...
.intemediateOperationN()
.terminalOperation();
为了可视化,让我们以以下代码为例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.reduce(0, Integer::sum);
List number=Arrays.asList(1,2,3,4);
int sum=numbers.stream()
.filter(n->n%2==0)
.map(n->n*n)
.reduce(0,整数::和);
filter
和map
是中间操作,reduce
是终端操作
我们从列表(numbers.stream()
)创建一个流,因此我们有:
|1,2,3,4|
筛选值(numbers.stream().filter(n->n%2==0)
):
|1,2,3,4 |------滤波器|
映射(numbers.stream().filter(n->n%2==0)。映射(n->n*n)
):
|1,2,3,4 |-----|过滤器|---|映射|
最后我们调用reduce
,这是终端操作,整个流程运行:
|1,2,3,4 |->4321->过滤器|->42->映射|->164->减少|->20
请注意,在调用终端操作之前,没有数据流过流。流是惰性的,当调用终端操作时,代码实际上会执行某些操作,如sum、toarray等,而filter、map是中间的,可能是重复的