如何将一种类型的 CompletableFuture 转换为另一种类型?
How do you transform a CompletableFuture of one type to another?
我目前将 CompletableFuture<X>
转换为 CompletableFuture<Void>
,如下所示,但我想知道是否有更好的方法。
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
public Void empty() {
return null;
}
您实际上是在尝试将 CompletableFuture
的完整值转换为 Void
类型的值。如果那个未来异常完成,大概你想传播任何异常。
CompletableFuture
提供了thenApply
用于此基本转换,但也可以使用其他方法。
在您的情况下,您将希望忽略源 future 和 return null
的值,因为 null
是类型 [=16] 的唯一可能值=].但是,编译器需要一些提示,表明您的目标类型是 Void
.
通过为 thenApply
的调用提供显式类型参数来显式
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).<Void> thenApply(c -> null);
}
或者通过转换为 lambda 表达式中的适当类型来显式
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> (Void) null);
}
您的解决方案实现了相同的结果,因为已知值的类型是正确的,但它涉及额外的方法调用
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
所有这些解决方案都将传播原始 CompletableFuture
.
的异常(如果有)
感谢 ,您也可以只使用 thenAccept
和 Consumer
什么都不做:
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}
任何其他类型的行为都相同。 thenApply
允许您对 CompletableFuture
.
的结果执行任何 Function
例如,我可以有一个未来,它意味着要用 String
完成,它意味着要转换为 Integer
。
public static void main(String[] args) throws Exception {
CompletableFuture<String> futureLine = CompletableFuture.supplyAsync(() -> "1234");
CompletableFuture<Integer> theNumber = futureLine.thenApply(Integer::parseInt);
System.out.println(theNumber.get());
}
thenApply
接收完成的值并通过将其传递给 Integer#parseInt(String)
的调用来转换它。由于 parseInt
有一个 return 类型的 int
,return 类型的 thenApply
被推断为 CompletableFuture<Integer>
.
我目前将 CompletableFuture<X>
转换为 CompletableFuture<Void>
,如下所示,但我想知道是否有更好的方法。
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
public Void empty() {
return null;
}
您实际上是在尝试将 CompletableFuture
的完整值转换为 Void
类型的值。如果那个未来异常完成,大概你想传播任何异常。
CompletableFuture
提供了thenApply
用于此基本转换,但也可以使用其他方法。
在您的情况下,您将希望忽略源 future 和 return null
的值,因为 null
是类型 [=16] 的唯一可能值=].但是,编译器需要一些提示,表明您的目标类型是 Void
.
通过为 thenApply
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).<Void> thenApply(c -> null);
}
或者通过转换为 lambda 表达式中的适当类型来显式
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> (Void) null);
}
您的解决方案实现了相同的结果,因为已知值的类型是正确的,但它涉及额外的方法调用
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
所有这些解决方案都将传播原始 CompletableFuture
.
感谢 thenAccept
和 Consumer
什么都不做:
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}
任何其他类型的行为都相同。 thenApply
允许您对 CompletableFuture
.
Function
例如,我可以有一个未来,它意味着要用 String
完成,它意味着要转换为 Integer
。
public static void main(String[] args) throws Exception {
CompletableFuture<String> futureLine = CompletableFuture.supplyAsync(() -> "1234");
CompletableFuture<Integer> theNumber = futureLine.thenApply(Integer::parseInt);
System.out.println(theNumber.get());
}
thenApply
接收完成的值并通过将其传递给 Integer#parseInt(String)
的调用来转换它。由于 parseInt
有一个 return 类型的 int
,return 类型的 thenApply
被推断为 CompletableFuture<Integer>
.