SAM conversions for Java interfaces in Kotlin - Time & Space Complexity
We want to understand how the time it takes to run code changes when using SAM conversions for Java interfaces in Kotlin.
Specifically, how does the cost grow when we create many instances using SAM conversions?
Analyze the time complexity of the following code snippet.
fun createRunnables(n: Int): List {
return List(n) { i ->
Runnable { println("Running task $i") }
}
}
This code creates a list of n Runnable objects using SAM conversion from a lambda.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Creating a Runnable instance inside a loop.
- How many times: Exactly
ntimes, once per list element.
Each Runnable is created once per loop iteration, so the total work grows directly with n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 Runnable creations |
| 100 | 100 Runnable creations |
| 1000 | 1000 Runnable creations |
Pattern observation: The work increases evenly as n grows; doubling n doubles the work.
Time Complexity: O(n)
This means the time to create all Runnable instances grows in a straight line with the number of instances.
[X] Wrong: "SAM conversions make instance creation instant or free."
[OK] Correct: Each SAM conversion still creates a new object, so the time grows with how many you make.
Understanding how SAM conversions affect performance helps you write clear and efficient Kotlin code when working with Java interfaces.
What if we reused a single Runnable instance instead of creating one per loop? How would the time complexity change?
Practice
What does SAM conversion allow you to do in Kotlin when working with Java interfaces?
Solution
Step 1: Understand SAM conversion purpose
SAM conversion lets Kotlin treat Java interfaces with a single abstract method as functional interfaces.Step 2: Identify how it simplifies code
This allows using lambda expressions instead of verbose anonymous classes for such interfaces.Final Answer:
Use a lambda expression instead of an anonymous class for interfaces with one method -> Option DQuick Check:
SAM conversion = Lambda for single-method Java interfaces [OK]
- Thinking SAM works for interfaces with multiple methods
- Confusing SAM conversion with Kotlin function to Java class conversion
- Assuming SAM converts Java interfaces to Kotlin classes
Which of the following is the correct Kotlin syntax to use SAM conversion with the Java Runnable interface?
val r = ???Solution
Step 1: Recall SAM conversion syntax for Runnable
Runnable is a Java interface with one method run(), so Kotlin allows lambda syntax: Runnable { ... }Step 2: Check each option's syntax
Runnable { println("Running") } correctly uses Runnable { println("Running") }. Others misuse method calls or lambda syntax.Final Answer:
Runnable { println("Running") } -> Option AQuick Check:
Runnable lambda = Runnable { ... } [OK]
- Trying to call run() method explicitly in lambda
- Using arrow syntax incorrectly inside Runnable
- Confusing method reference with lambda syntax
What will be the output of this Kotlin code using SAM conversion with Comparator?
val list = listOf("apple", "banana", "cherry")
val sorted = list.sortedWith(Comparator { a, b -> b.length - a.length })
println(sorted)Solution
Step 1: Understand the Comparator lambda
The lambda compares strings by length descending: b.length - a.length.Step 2: Sort the list by string length descending
"banana" (6), "apple" (5), "cherry" (6). Since "banana" and "cherry" have same length, their order depends on original order.Step 3: Determine sorted order
Between "banana" and "cherry", "banana" comes first in original list, so it stays first. Then "cherry", then "apple" last.Final Answer:
["banana", "apple", "cherry"] -> Option CQuick Check:
Sorted by length descending = [banana, apple, cherry] [OK]
- Assuming ascending order instead of descending
- Mixing up a and b in comparator lambda
- Ignoring stable sort behavior for equal lengths
Identify the error in this Kotlin code using SAM conversion with a Java interface ActionListener:
val listener = ActionListener { event ->
println("Clicked")
}
button.addActionListener(listener)Solution
Step 1: Check if ActionListener is a Java interface with one method
ActionListener is a Java interface with a single method actionPerformed(ActionEvent).Step 2: Verify SAM conversion applicability
SAM conversion applies only to Java interfaces with exactly one abstract method, so it should work here.Step 3: Identify the actual error
If the code does not compile, it might be because the Kotlin compiler does not recognize ActionListener as a SAM interface due to missing Java interop or import.Final Answer:
SAM conversion works only if the interface is a Java interface with one method -> Option AQuick Check:
SAM conversion requires Java single-method interface [OK]
- Assuming Kotlin interfaces support SAM conversion
- Thinking parameter name must be fixed
- Believing anonymous objects are always required
You want to use SAM conversion to simplify this Java interface usage in Kotlin:
public interface Task {
void execute(int times);
}Which Kotlin lambda expression correctly uses SAM conversion for Task?
Solution
Step 1: Confirm Task is a Java interface with one method
Task has one method execute(int times), so SAM conversion applies.Step 2: Write correct lambda syntax for SAM conversion
The lambda must accept one parameter (times) matching the method signature: Task { times -> ... }Step 3: Check each option
Task { times -> println("Executed $times times") } correctly uses Task { times -> println(...) }. Others misuse method calls or omit parameter.Final Answer:
Task { times -> println("Executed $times times") } -> Option BQuick Check:
SAM lambda matches method parameters = Task { times -> println("Executed $times times") } [OK]
- Calling method name explicitly in lambda
- Omitting lambda parameter when method requires one
- Using wrong method name in lambda expression
Ready to prove it?
Pass the test and this pattern moves unknown
