Qual é a diferença entre 'CompletionStage' e 'CompletableFuture'

Eu vi um exemplo em cada um deles, mas preciso saber exatamente qual é a diferença profunda, porque às vezes acho que posso usar os dois para obter o mesmo resultado, então quero saber para poder escolher o correto 1?

qual é o benefício de usar cada um deles?

Como este exemplo, ambos são trabalhados:

public CompletionStage<Result> getNextQueryUUID() {
    return CompletableFuture.supplyAsync(() -> {
        String nextId = dbRequestService.getNextRequestQueryUUID();
        return ok(nextId);
    }, executor);
}


public CompletableFuture<Result> getNextQueryUUID() {
    return CompletableFuture.supplyAsync(() -> {
        String nextId = dbRequestService.getNextRequestQueryUUID();
        return ok(nextId);
    }, executor);
}

Este exemplo é executado emPlay framework.

questionAnswers(3)

yourAnswerToTheQuestion