Tho*_*ras 5 java java-8 completable-future
我有一个代码:
CompletableFuture<Integer> c1 = new CompletableFuture<Integer>()
.thenApply((data) -> data * 2);
c1.thenAccept(System.out::println);
c1.complete(20);
CompletableFuture<Integer> c2 = new CompletableFuture<>();
c2.thenApply(data -> data * 2)
.thenAccept(System.out::println);
c2.complete(20);
Run Code Online (Sandbox Code Playgroud)
输出:
20 40
题:
新的CompletableFuture < 整数 >()
首先要注意的事情是,方法CompletableFuture
(例如thenApply
,thenAccept
等)返回一个新的 CompletableFuture
实例.这形成了一种"链",其中每个新阶段都依赖于它从其父阶段创建的阶段.当阶段完成时,无论是正常还是异常,结果都会被推送到其所有相关的未完成*阶段(同一阶段可以有多个依赖阶段).
*正如您将在下面看到的那样,即使其父母尚未完成,您也可以完成一个阶段.如果父级完成,则完成的依赖阶段将不会被调用,因为它已经完成.Holger对另一个问题的回答简要介绍了这种情况的后果.
在您的第一个示例中,您有以下内容:
CompletableFuture<Integer> c1 = new CompletableFuture<Integer>()
.thenApply((data) -> data * 2);
c1.thenAccept(System.out::println);
c1.complete(20);
Run Code Online (Sandbox Code Playgroud)
这c1
是由thenApply
而非产生的阶段new CompletableFuture<Integer>()
.当你打电话c1.complete(20)
,你都完成了thenApply
与给定值阶段(正常)( 20
).调用complete
等同于Function
转换前一阶段的结果并返回20
.现在,它thenApply
已完成,thenAccept
它将导致20
打印到控制台的值.
在第二个示例中,您有以下内容:
CompletableFuture<Integer> c2 = new CompletableFuture<>();
c2.thenApply(data -> data * 2)
.thenAccept(System.out::println);
c2.complete(20);
Run Code Online (Sandbox Code Playgroud)
这c2
是由舞台new CompletableFuture<>()
的父母产生的thenApply
舞台.所以现在当你打电话的时候c2.complete(20)
你正在完成将值推送到的根阶段thenApply
.在Function
随后通过转换乘以它的价值2
,推动该结果thenAccept
.这导致40
打印到控制台.
您必须<Integer>
在第一个示例中重复的原因是因为没有它,编译器无法推断第一个阶段的类型.签名thenApply
是:
<U> CompletableFuture<U> thenApply(Function<? super T, ? extends U>)
Run Code Online (Sandbox Code Playgroud)
由此T
类型CompletableFuture
(调用方法的类型)确定.在U
由确定Function
和,一个变量赋值的左手侧在适用情况下,在一定程度上.这意味着当您使用菱形运算符(<>
)时,您实际上正在使用以下内容:
CompletableFuture<Integer> c = new CompletableFuture<Object>()
.thenApply(data -> data * 2);
// same as...
CompletableFuture<Integer> c = new CompletableFuture<>()
.thenApply(data -> data * 2);
Run Code Online (Sandbox Code Playgroud)
因为所有编译器都知道data
它的类型是Object
乘法无效; 一个Object
不能乘以2
.请注意,如果您只是将Function
from 更改为data -> data * 2
to ,则上述内容将有效data -> 2
(但显然这两个函数不相同).这是因为作业的左侧与结果有关thenApply
,而不是new CompletableFuture<>()
.
当你明确指定<Integer>
编译器然后知道阶段的输入类型(T
),这意味着它知道是一个; 一个可以乘以.thenApply
Integer
data
Integer
Integer
2
归档时间: |
|
查看次数: |
196 次 |
最近记录: |