2016-05-11 6 views
4

Ich konvertiere derzeit meine CompletableFuture<X> in CompletableFuture<Void> wie unten gezeigt, aber ich fragte mich, ob es einen besseren Weg gab.Wie transformiert man eine CompleableFuture eines Typs in einen anderen?

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

public Void empty() { 
    return null; 
} 

Antwort

4

Sie versuchen, effektiv Void den fertiggestellten Wert Ihrer CompletableFuture in einen Wert vom Typ zu transformieren. Vermutlich möchten Sie eine Ausnahme weitergeben, wenn diese Zukunft in Ausnahmefällen abgeschlossen wurde.

CompletableFuture bietet thenApply für diese grundlegende Transformation, aber andere Methoden können ebenfalls verwendet werden.

In Ihrem Fall sollten Sie den Wert aus der Quelle Zukunft ignorieren und null zurückkehren, da null der einzig mögliche Wert für den Void Typen ist. Es muss jedoch ein Hinweis für den Compiler angegeben werden, auf den Sie den Typ Void ausrichten.

entweder explizit sein, indem eine explizite Typargument des Aufrufs thenApply

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

oder explizit sein Bereitstellung von

in dem Lambda-Ausdruck in den entsprechenden Typ Gießens
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) { 
    return realChannel.write(engineToSocketData).thenApply(c -> (Void) null); 
} 

Ihre Lösung das gleiche erreicht Ergebnis, da bekannt ist, dass der Wert vom richtigen Typ ist, aber es beinhaltet einen zusätzlichen Methodenaufruf

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

Alle diese Lösungen propagieren die Ausnahme, falls vorhanden, der ursprünglichen CompletableFuture.


Das Verhalten ist für jeden anderen Typ gleich. thenApply können Sie jede Function auf das Ergebnis einer CompletableFuture ausführen.

Zum Beispiel kann ich eine Zukunft haben, die mit String abgeschlossen werden soll, die in eine Integer umgewandelt werden soll.

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 empfängt den beendet Wert und wandelt sie, indem es einen Aufruf von Integer#parseInt(String) vorbei. Da parseInt einen Rückgabetyp von int hat, wird der Rückgabetyp thenApply als CompletableFuture<Integer> gewertet.

Verwandte Themen