Artyom Karnov
Artyom Karnov

Reputation: 597

How to convert Java lambda based on functional interface to Kotlin one?

I have the next java functional interface

@FunctionalInterface
public interface FragmentHandler {
     void onFragment(DirectBuffer buffer, int offset, int length, Header header);
}

I have a very simple interface implementation

public static FragmentHandler printStringMessage(int streamId) {
    return (buffer, offset, length, header) -> {
        byte[] data = new byte[length];
        buffer.getBytes(offset, data);
        System.out.println(String.format("Message to stream %d from session %d (%d@%d) <<%s>>", streamId, header.sessionId(), length, offset, new String(data)));
    };
}

I'd like to write the same structure using Kotlin

fun printStringMessage(streamId: Int): FragmentHandler {
    val lambda: (DirectBuffer, Int, Int, Header) -> Unit = { buffer: DirectBuffer, length: Int, offset: Int, header: Header ->
        val data = ByteArray(length)
        buffer.getBytes(offset, data)
        println(String.format("Message to stream %d from session %d (%d@%d) <<%s>>", streamId, header.sessionId(), length, offset, String(data)))
    }
}

But this code is not valid. I don't undersrand how to implement the same peace of logic in Kotlin.

Upvotes: 2

Views: 124

Answers (2)

Birju Vachhani
Birju Vachhani

Reputation: 6353

Here is the right answer of your question:

fun printStringMessage(streamId: Int): FragmentHandler {
    val lambda = FragmentHandler { buffer: DirectBuffer, length: Int, offset: Int, header: Header ->
        val data = ByteArray(length)
        buffer.getBytes(offset, data)
        println(String.format("Message to stream %d from session %d (%d@%d) <<%s>>", streamId, header.sessionId(), length, offset, String(data)))
    }
return lambda
}

Upvotes: 0

zsmb13
zsmb13

Reputation: 89548

You can use a SAM constructor to specify the interface you want your lambda to represent, like this:

fun printStringMessage(streamId: Int): FragmentHandler {
    val fragmentHandler = FragmentHandler { buffer: DirectBuffer, length: Int, offset: Int, header: Header ->
        val data = ByteArray(length)
        buffer.getBytes(offset, data)
        println(String.format("Message to stream %d from session %d (%d@%d) <<%s>>", streamId, header.sessionId(), length, offset, String(data)))
    }
    return fragmentHandler
}

This would also allow you to leave off the explicit types from the parameters, if you wanted to, plus you can of course return the instance directly:

fun printStringMessage(streamId: Int): FragmentHandler {
    return FragmentHandler { buffer, length, offset, header ->
        val data = ByteArray(length)
        buffer.getBytes(offset, data)
        println(String.format("Message to stream %d from session %d (%d@%d) <<%s>>", streamId, header.sessionId(), length, offset, String(data)))
    }
}

Upvotes: 2

Related Questions