Si tu Futurees el resultado de una llamada a un ExecutorServicemétodo (por ejemplo submit()), lo más fácil sería usar el CompletableFuture.runAsync(Runnable, Executor)método en su lugar.
Desde
Runnbale myTask = ... ;
Future<?> future = myExecutor.submit(myTask);
a
Runnbale myTask = ... ;
CompletableFuture<?> future = CompletableFuture.runAsync(myTask, myExecutor);
A CompletableFuturecontinuación, se crea "de forma nativa".
EDITAR: Continuando con los comentarios de @SamMefford corregidos por @MartinAndersson, si desea pasar a Callable, debe llamar supplyAsync(), convirtiendo el Callable<T>en a Supplier<T>, por ejemplo, con:
CompletableFuture.supplyAsync(() -> {
try { return myCallable.call(); }
catch (Exception ex) { throw new RuntimeException(ex); }
}, myExecutor);
Debido a que T Callable.call() throws Exception;lanza una excepción y T Supplier.get();no lo hace, debe detectar la excepción para que los prototipos sean compatibles.