9

現在、以下に示すように変換CompletableFuture<X>してCompletableFuture<Void>いますが、もっと良い方法があるかどうか疑問に思っていました。

@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
    return realChannel.write(engineToSocketData).thenApply(c -> empty());
}

public Void empty() {
    return null;
}
4

1 に答える 1

9

CompletableFutureyour の完成した値を type の値に効果的に変換しようとしていますVoid。おそらく、その未来が例外的に完了した場合、例外を伝播したいと思うでしょう。

CompletableFuturethenApplyこの基本的な変換を提供しますが、他の方法も使用できます。

あなたの場合、ソース future からの値を無視して return にする必要があります。 type の唯一の可能な値だnullからです。ただし、 type をターゲットにしていることをコンパイラに示すヒントが必要です。nullVoidVoid

の呼び出しに明示的な型引数を指定して明示的にするかthenApply

public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
    return realChannel.write(engineToSocketData).<Void> thenApply(c -> null);
}

または、ラムダ式で適切な型にキャストして明示的にします

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());
}

これらのソリューションはすべて、元の .xml の例外があればそれを伝播しますCompletableFuture

Luisに感謝します。何もしないで使用することもできますthenAcceptConsumer

public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
    return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}

動作は他のタイプでも同じです。の結果thenApplyに対して任意の操作を実行できます。FunctionCompletableFuture

たとえば、 に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>ます。

于 2016-05-11T03:20:11.010 に答える