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 threadthenAccept: 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.425thenCompose: 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
- Creazione e completamento di CompletableFuture
- Concatenare con thenApply e thenCompose
- Combinare i future: allOf e anyOf
- Gestione degli errori e pipeline HTTP asincrona