Java Reference
In-Depth Information
Listing 11.20. Refactoring the findPrices method to return a stream of
Future s
public Stream<CompletableFuture<String>> findPricesStream(String product) {
return shops.stream()
.map(shop -> CompletableFuture.supplyAsync(
() -> shop.getPrice(product), executor))
.map(future -> future.thenApply(Quote::parse))
.map(future -> future.thenCompose(quote ->
CompletableFuture.supplyAsync(
() -> Discount.applyDiscount(quote), executor)));
}
At this point, you add a fourth map operation on the Stream returned by the findPricesStream
method to the three already performed inside that method. This new operation simply registers
an action on each CompletableFuture; this action consumes the value of the CompletableFuture
as soon as it completes. The Java 8 CompletableFuture API provides this feature via the
thenAccept method, which take as argument a Consumer of the value with which it completes.
In this case, this value is the String returned by the discount services and containing the name of
a shop together with the discounted price of the requested product for that shop, and the only
action you want to perform to consume this value is to print it:
findPricesStream("myPhone").map(f -> f.thenAccept(System.out::println));
Note that, as you've already seen for the thenCompose and thenCombine methods, the
thenAccept method also has an Async variant named thenAcceptAsync. The Async variant
schedules the execution of the Consumer passed to it on a new thread from the thread pool
instead of directly performing it using the same thread that completed the CompletableFuture.
Because you want to avoid an unnecessary context switch, and more importantly you want to
react to the completion of the CompletableFuture as soon as possible (instead of risking having
to wait for a new thread to be available), you don't use this variant here.
Because the thenAccept method already specifies how to consume the result produced by the
CompletableFuture when it becomes available, it returns a Completable-Future<Void>. As a
result, the map operation will return a Stream-<Completable-Future<Void>>. There's not much
you can do on a Completable-Future<Void> except wait for its completion, but this is exactly
what you need. You also want to give the slowest shop a chance to provide its response and print
 
Search WWH ::




Custom Search