Friday, 28 November 2025

Kotlin: From List To Map

So I've been trying to make a Map from a List in Kotlin, and as I have not much experience with Kotlin and not much experience with Maps, I turn to the Internet.

Funnily enough, after getting it working, my IDE keeps giving me subtle hints that it can be shorter and more concise.

I thought it would be nice to put the steps here.

val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
val firstTry = primaryKeys.map { it to getUser(it) }

In the example above it's not a Map yet, but it's a good first step.

As you can tell, it transforms your list into another List of type List<Pair<Long, User>>.

Kotlin has a toMap() method that does what we want.

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.map { it to getUser(it) }.toMap()
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Now my IDE tells me this can be shortened.

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.associate { it to getUser(it) }
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Now my IDE tells me this can be shortened AGAIN!

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.associateWith { getUser(it) }
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Nice!

References

Syntax Highlighter
https://highlight.hohli.com/

Thursday, 20 November 2025

Kotlin: Redundant SAM constructor

Kotlin lambdas are fully compatible with Java functional interfaces.

But sometimes you need to give Kotlin a little nudge, using a SAM constructor.

SAM constructors (Single Abstract Method) allow you to convert a lambda expression to an instance of a functional interface. The syntax is pretty straightforward.

FunctionalInterfaceName { lambda_function }

The message in the title appears when you use a SAM constructor, when you don't have to. Kotlin is smart enough to create the appropriate anonymous class without us being specific in most cases.

I notice this happening sometimes when I have IntelliJ convert my Java class automatically to Kotlin.

A simple example:

// Java
public Builder addMapping(FieldMetadata field, Supplier<?> valueSupplier) {...}
// redundant Kotlin
val fieldMapping = FieldMapping.builder()
.addMapping(OrderItemField.ITEM_NR), Supplier { orderRepository.getOrderItem })
.build()
// correct Kotlin
val fieldMapping = FieldMapping.builder()
.addMapping(OrderItemField.ITEM_NR) { orderRepository.getOrderItem }
.build()

References

Medium - Idiomatic Kotlin: Lambdas and SAM constructors
https://medium.com/tompee/idiomatic-kotlin-lambdas-and-sam-constructors-fe2075965bfb