2016-05-11 1 views
4

Je convertis actuellement mon CompletableFuture<X> en CompletableFuture<Void> comme indiqué ci-dessous mais je me demandais s'il y avait un meilleur moyen.Comment transformer un CompletableFuture d'un type en un autre?

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

public Void empty() { 
    return null; 
} 

Répondre

4

Vous essayez de transformer efficacement la valeur complète de votre CompletableFuture en une valeur de type Void. Vraisemblablement vous voulez propager n'importe quelle exception si ce futur a été accompli exceptionnellement.

CompletableFuture fournit thenApply pour cette transformation de base, mais d'autres méthodes peuvent également être utilisées.

Dans votre cas, vous aurez envie d'ignorer la valeur de la future source et retour null, puisque null est la seule valeur possible pour le type Void. Cependant, il doit y avoir une indication pour le compilateur que vous ciblez le type Void.

Soit être explicite en fournissant un argument de type explicite à l'invocation de thenApply

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

ou être explicite par coulée du type approprié dans l'expression lambda

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

Votre solution permet d'obtenir le même résultat, car la valeur est connue pour être du type correct, mais elle implique une invocation de méthode supplémentaire

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

Toutes ces solutions propageront l'exception, le cas échéant, de CompletableFuture d'origine.


Le comportement est le même pour tout autre type. thenApply vous permet d'effectuer n'importe quel Function sur le résultat d'un CompletableFuture. Par exemple, je peux avoir un avenir qui est censé compléter avec String qui est censé être converti en 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 reçoit la valeur terminée et le transforme en le passant à l'invocation de Integer#parseInt(String). Puisque parseInt a un type de retour de int, le type de retour de thenApply est déduit à CompletableFuture<Integer>.