我目前将CompletableFuture<X>
转换为CompletableFuture<Void>
,如下所示,但我想知道是否有更好的方式。
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
public Void empty() {
return null;
}
答案 0 :(得分:7)
您有效地尝试将CompletableFuture
的已完成值转换为Void
类型的值。据推测,如果未来异常完成,您希望传播任何异常。
CompletableFuture
为此基本转换提供了thenApply
,但也可以使用其他方法。
在您的情况下,您希望忽略来源未来的值并返回null
,因为null
是Void
类型唯一可能的值。但是,您需要为编译器提供一些提示,并将其定位到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
的例外(如果有)。
感谢Luis,您也可以thenAccept
使用Consumer
无所事事:
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}
任何其他类型的行为都是相同的。 thenApply
可让您对Function
的结果执行任何CompletableFuture
。
例如,我可以拥有一个意味着完成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
的返回类型为int
,因此thenApply
的返回类型会推断为CompletableFuture<Integer>
。