/** * Transform the input futures into a single future, using the provided * transform function. The transformation follows the same semantics as as * {@link Futures#transformAsync(ListenableFuture, AsyncFunction, Executor)} and the input * futures are combined using {@link Futures#allAsList}. * * @param a a ListenableFuture to combine * @param b a ListenableFuture to combine * @param function the implementation of the transform * @return a ListenableFuture holding the result of function.apply() */ public static <Z, A, B> ListenableFuture<Z> asyncTransform2( ListenableFuture<A> a, ListenableFuture<B> b, final AsyncFunction2<Z, ? super A, ? super B> function, final Executor executor) { return transform( Arrays.asList(a, b), (AsyncFunction<List<Object>, Z>) results -> function.apply((A) results.get(0), (B) results.get(1)), executor); }