Home > Blockchain >  Kotlin Syntax for whenCompleteAsync(BiConsumer,Executor)
Kotlin Syntax for whenCompleteAsync(BiConsumer,Executor)

Time:12-05

How do I implement a function in Kotlin for below method signature. I am facing issues getting the syntax correct.

public CompletableFuture<T> whenCompleteAsync(
        BiConsumer<? super T, ? super Throwable> action, Executor executor)

CodePudding user response:

The analogue to Java's BiConsumer<? super T, ? super Throwable> generic type would be written in Kotlin as BiConsumer<in T, in Throwable>. The in keyword indicates that the generic type T is contravariant.

This is how whenCompleteAsync function could be implemented in Kotlin using the provided method signature:

fun <T> whenCompleteAsync(
    action: BiConsumer<in T, in Throwable>, 
    executor: Executor
): CompletableFuture<T> {
    val future = CompletableFuture<T>()

    executor.execute {
        try {
            val result = future.get()
            action.accept(result, null)
        } catch (e: Throwable) {
            action.accept(null, e)
        }
    }

    return future
}

This function creates a new CompletableFuture and executes the provided action using the given executor when the future completes. The action is passed the result of the future (or null if the future completed exceptionally) and the exception thrown by the future (or null if the future completed successfully).

Usage:

val future = whenCompleteAsync(
    BiConsumer { result, ex ->
        if (ex != null) {
            // Handle exception
        } else {
            // Handle result
        }
    },
    Executors.newSingleThreadExecutor()
)

In this example, the whenCompleteAsync function is used to create a new CompletableFuture that will execute the provided BiConsumer on a single-threaded executor when the future completes. The BiConsumer will receive the result of the future or the exception thrown by the future, depending on how the future completed. Use this information to handle the result or exception as appropriate.


In Kotlin no need to use BiConsumer interface (unless it is reqired for some reason). Instead it is possible to use Kotlin function with two arguments and simplify the example:

fun <T> whenCompleteAsync(
    action: (T?, Throwable?) -> Unit,
    executor: Executor
): CompletableFuture<T> {
    val future = CompletableFuture<T>()

    executor.execute {
        try {
            val result = future.get()
            action(result, null)
        } catch (e: Throwable) {
            action(null, e)
        }
    }

    return future
}

val future = whenCompleteAsync(
    { result, ex ->
        if (ex != null) {
            // Handle exception
        } else {
            // Handle result
        }
    },
    Executors.newSingleThreadExecutor()
)
  • Related