Run a list of futures:

List<String> taskNames = ...
taskNames.stream()
.map(task->CompletableFuture
.supplyAsync(() -> {
System.out.println(task);
return true;
})).map(CompletableFuture::join).collect(Collectors.toList());

Future

  • get: a blocking method that waits until the completable future is finished – this is not a java 8 feature!

CompletableFuture

  • supplyAsync:  runs a supplier asynchronously.
  • runAsync:runsRunnable asynchronously.
  • thenApply(map): process the execution result of the supplyAsync and return it
  • thenAccept: process the execution result and process the result in place without returning anything.
  • allOf: run multiple futures. Doesn’t return the result of all the completableFutures. Need to handle each result alone.

 

  • thenRun: runs a runnable after the supplyAsync or runAsync.

 

  • Async Threads: Runnable and Supply, we can use them to return completable future.
  • Monadic design pattern: Combining completable futures in chain using thenCompose and the thenApply which receives the result of the previous completable future.
  • thenCompose(flatMap): receives a function that returns another object of the same type. The input of the lambda is the completableFuture result just like the thenApply.
  • thenCombine: used when we want to use the result of two futures.
  • thenAcceptBoth: doesn’t send result down the future

Functional Interfaces in Java 8

Predicate

Represents a predicate (boolean-valued function) of one argument.

Predicate isAnAdult = age -> age >= 18;

we can actually try using our new predicate in a stream.

 

Consumer

Represents an operation that accepts a single input argument and returns no result.

Consumer ticketPrinter = ticket -> ticket.print();

The new forEach method in the Iterable interface takes the Consumer interface as an argument:

Collection tickets = getTicketsToPrint(); 
tickets.forEach(ticket -> ticket.print());

Supplier

This is kind of a factory. It takes no arguments, and just gives you a result. Perfect for returning an instance.

Supplier ticketHandlerCreator = () -> new TicketHandler();

Another solution is to use the constructor reference.

Supplier ticketHandlerCreator = TicketHandler::new;

Function<T,R>

Represents a function that accepts one argument and produces a result. Let’s just go straight to an example.