thenApply-does-not-modify-future

  • thenApply does NOT modify the CompletableFuture it is called on.
  • thenApply creates a new CompletableFuture.
GT-snapshot

Code

package com.glassthought.sandbox

import gt.sandbox.util.output.Out
import kotlinx.coroutines.runBlocking
import java.util.concurrent.CompletableFuture

val out = Out.standard()

fun main() = runBlocking {
  val future = CompletableFuture.supplyAsync {
    out.println("supplyAsync")
    "Jon Snow"
  }

  out.println("thenApply().get(): " + future.thenApply {
    out.println("thenApply")
    "Hello: $it"
  }.get())

  out.println("""future.get(): [${future.get()}]""") // Output: Hello, CompletableFuture!
  println()
}

Command to reproduce:

gt.sandbox.checkout.commit 1c4b9d2596b1f10289ca \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run"

Recorded output of command:

[2024-11-22T04:46:49.146281Z][elapsed-since-start:   43ms][tname:ForkJoinPool.commonPool-worker-1/tid:20] supplyAsync
[2024-11-22T04:46:49.165936Z][elapsed-since-start:   52ms][tname:ForkJoinPool.commonPool-worker-1/tid:20] thenApply
[2024-11-22T04:46:49.166359Z][elapsed-since-start:   53ms][tname:main/tid:1] thenApply().get(): Hello: Jon Snow
[2024-11-22T04:46:49.166505Z][elapsed-since-start:   53ms][tname:main/tid:1] future.get(): [Jon Snow]

Key Points About thenApply

  1. thenApply Creates a New Future:

    • When you call thenApply, a new CompletableFuture is created. This new future holds the transformed result of the computation once the original future completes.
  2. The Original Future Remains Unchanged:

    • The result of the original CompletableFuture (future.get() in your code) is unaffected by the thenApply call. It still holds the value "Jon Snow".
  3. Accessing the Transformed Result:

    • To retrieve the transformed result (e.g., "Hello Jon Snow" in your example), you need to call .get() or .join() on the CompletableFuture returned by thenApply.

Backlinks