Java Academy · Aula

Encadeamento com thenApply e thenCompose

Transforme resultados com thenApply e aplique etapas assíncronas flatMap com thenCompose para evitar futures aninhados.

Aula 2 de 413 etapas

Encadeamento com thenApply e thenCompose é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

thenApply: transformando o resultado

thenApply(Function) aplica uma função síncrona ao resultado de um futuro concluído, retornando um novo futuro com o tipo transformado. Ele não inicia uma nova tarefa assíncrona.

CompletableFuture<String> nameFuture = CompletableFuture
    .supplyAsync(() -> 42L)            // CF<Long>
    .thenApply(id -> "User#" + id);    // CF<String>
System.out.println(nameFuture.join()); // "User#42"

thenApplyAsync: transformando em uma thread

thenApplyAsync executa a função de transformação no ForkJoinPool (ou em um executor fornecido), liberando imediatamente a thread que concluiu a operação.

CompletableFuture<String> result = fetchUserAsync()
    .thenApplyAsync(user -> serialize(user)); // runs on pool thread

thenAccept: consumindo sem retornar

thenAccept(Consumer) processa o resultado, mas retorna CompletableFuture<Void>. Utilize-o como última etapa de um fluxo quando não precisar passar um valor adiante.

fetchUserAsync()
    .thenApply(User::getName)
    .thenAccept(name -> System.out.println("Hello, " + name));

thenRun: executando após a conclusão

thenRun(Runnable) executa uma tarefa depois que o futuro é concluído, ignorando o resultado. É útil para fechar recursos ou acionar efeitos colaterais.

downloadFileAsync(url)
    .thenRun(() -> System.out.println("Download complete"));

Encadeando várias chamadas thenApply

Várias chamadas de thenApply formam um fluxo. Cada etapa recebe a saída da etapa anterior.

CompletableFuture<Double> result = CompletableFuture
    .supplyAsync(() -> "  42.5  ")
    .thenApply(String::trim)
    .thenApply(Double::parseDouble)
    .thenApply(d -> d * 1.21); // apply 21% VAT
System.out.println(result.join()); // 51.425

thenCompose: achatando futuros aninhados

thenCompose(Function<T, CompletionStage<U>>) funciona como flatMap para futuros. Ele evita CompletableFuture<CompletableFuture<T>> ao achatar o futuro aninhado.

// Wrong with thenApply — returns CF<CF<Order>>:
CompletableFuture<CompletableFuture<Order>> nested =
    fetchUser(id).thenApply(u -> fetchLatestOrder(u.getId()));
// Correct with thenCompose — returns CF<Order>:
CompletableFuture<Order> flat =
    fetchUser(id).thenCompose(u -> fetchLatestOrder(u.getId()));

thenCompose para chamadas assíncronas sequenciais

Utilize thenCompose quando cada etapa assíncrona depender do resultado da etapa anterior, tornando as etapas sequenciais e dependentes dos resultados.

fetchUser(userId)
    .thenCompose(user -> fetchOrders(user.getId()))
    .thenCompose(orders -> computeTotal(orders))
    .thenAccept(total -> System.out.println("Total: " + total));

thenApply versus thenCompose

thenApply: mapeia T -> U (transformação síncrona). thenCompose: mapeia T -> CompletableFuture<U> e achata o resultado. Utilize thenCompose quando a próxima etapa também for assíncrona.

Lidando com erros intermediários com handle

handle(BiFunction<T, Throwable, U>) é chamado tanto quando o futuro é concluído normalmente quanto quando é concluído com uma exceção, permitindo recuperar-se de erros ou transformá-los no meio do fluxo.

fetchUser(id)
    .thenApply(User::getProfile)
    .handle((profile, ex) -> {
        if (ex != null) return Profile.empty(); // recover
        return profile;
    })
    .thenAccept(System.out::println);

whenComplete: efeito colateral após qualquer resultado

whenComplete(BiConsumer) é chamado após a conclusão (normal ou excepcional) para registro ou limpeza. Diferentemente de handle, ele não altera o resultado.

fetchAsync()
    .whenComplete((result, ex) -> {
        if (ex != null) log.error("Failed", ex);
        else            log.info("Result: " + result);
    });

Exemplo de fluxo sem bloqueio

Componha um fluxo totalmente sem bloqueio: busque o usuário, busque os pedidos dele e calcule um resumo — todas as etapas são executadas de forma assíncrona, cada uma dependendo da anterior.

CompletableFuture<String> summary =
    fetchUser(userId)
        .thenCompose(u -> fetchOrders(u.getId()))
        .thenApply(orders -> orders.size() + " orders")
        .exceptionally(ex -> "Error: " + ex.getMessage());
System.out.println(summary.join());

Verificação rápida

Quando você deve utilizar thenCompose em vez de thenApply?

Recapitulação

thenApply transforma valores síncronos em um fluxo. thenCompose encadeia etapas assíncronas (flatMap para futuros). handle / whenComplete adicionam tratamento de erros e efeitos colaterais. Crie fluxos da esquerda para a direita para facilitar a leitura.

Grátis para começar

Aprenda Java com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
104
Aulas
374

Perguntas Frequentes

A aula “Encadeamento com thenApply e thenCompose” é grátis?

Sim — o texto completo de “Encadeamento com thenApply e thenCompose” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Encadeamento com thenApply e thenCompose”?

Transforme resultados com thenApply e aplique etapas assíncronas flatMap com thenCompose para evitar futures aninhados. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Encadeamento com thenApply e thenCompose”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Criação e Conclusão de CompletableFutures
  2. Encadeamento com thenApply e thenCompose
  3. Combinação de Futures: allOf e anyOf
  4. Tratamento de Erros e Pipeline HTTP Assíncrono
← Voltar para Java Academy