0Pricing
Java Academy · Lezione

Concatenare con thenApply e thenCompose

Trasformi i risultati con thenApply e concateni i passaggi asincroni flatMap con thenCompose per evitare future annidati.

Concatenare con thenApply e thenCompose è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

thenApply: trasformare il risultato

thenApply(Function) applica una funzione sincrona al risultato di un future completato e restituisce un nuovo future del tipo trasformato. Non avvia una nuova attività asincrona.

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

thenApplyAsync: trasformare su un thread

thenApplyAsync esegue la funzione di trasformazione nel ForkJoinPool (o in un executor fornito), liberando immediatamente il thread che ha completato il future.

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

thenAccept: consumare senza restituire

thenAccept(Consumer) elabora il risultato, ma restituisce CompletableFuture<Void>. Lo utilizzi come ultimo passaggio di una pipeline quando non deve passare avanti alcun valore.

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

thenRun: eseguire dopo il completamento

thenRun(Runnable) esegue un'attività dopo il completamento del future, ignorandone il risultato. È utile per chiudere risorse o attivare effetti collaterali.

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

Concatenare più chiamate thenApply

Più chiamate a thenApply formano una pipeline. Ogni passaggio riceve l'output del passaggio precedente.

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: appiattire future annidati

thenCompose(Function<T, CompletionStage<U>>) è l'equivalente di flatMap per i future. Evita CompletableFuture<CompletableFuture<T>> appiattendo il future annidato.

// 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 per chiamate asincrone sequenziali

Utilizzi thenCompose quando ogni passaggio asincrono dipende dal risultato di quello precedente, rendendo i passaggi sequenziali e dipendenti dai risultati.

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

thenApply e thenCompose a confronto

thenApply: mappa T -> U (trasformazione sincrona). thenCompose: mappa T -> CompletableFuture<U> e appiattisce il risultato. Utilizzi compose quando anche il passaggio successivo è asincrono.

Gestire gli errori intermedi con handle

handle(BiFunction<T, Throwable, U>) viene chiamato sia quando il future viene completato normalmente sia quando viene completato con un'eccezione, consentendo di recuperare dagli errori o trasformarli a metà della pipeline.

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

whenComplete: effetto collaterale dopo qualsiasi esito

whenComplete(BiConsumer) viene chiamato dopo il completamento, normale o eccezionale, per eseguire attività di logging o pulizia. A differenza di handle, non modifica il risultato.

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

Esempio di pipeline non bloccante

Componga una pipeline completamente non bloccante: recuperi l'utente, recuperi i suoi ordini e calcoli un riepilogo. Tutti i passaggi vengono eseguiti in modo asincrono e ciascuno dipende dal precedente.

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 rapida

Quando è opportuno utilizzare thenCompose invece di thenApply?

Riepilogo

thenApply trasforma valori sincroni in una pipeline. thenCompose concatena passaggi asincroni (è l'equivalente di flatMap per i future). handle / whenComplete aggiungono la gestione degli errori e gli effetti collaterali. Costruisca le pipeline da sinistra a destra per migliorarne la leggibilità.

Domande Frequenti

La lezione «Concatenare con thenApply e thenCompose» è gratuita?

Sì — il testo completo di «Concatenare con thenApply e thenCompose» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Concatenare con thenApply e thenCompose»?

Trasformi i risultati con thenApply e concateni i passaggi asincroni flatMap con thenCompose per evitare future annidati. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Concatenare con thenApply e thenCompose»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Creazione e completamento di CompletableFuture
  2. Concatenare con thenApply e thenCompose
  3. Combinare i future: allOf e anyOf
  4. Gestione degli errori e pipeline HTTP asincrona
← Torna a Java Academy