Custom delegated properties in Kotlin - Time & Space Complexity
When using custom delegated properties in Kotlin, it's important to understand how the time to get or set a property changes as your program runs.
We want to know how the cost of accessing or updating these properties grows with usage.
Analyze the time complexity of the following Kotlin code using a custom delegate.
class ExampleDelegate {
private var storedValue: String = ""
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): String {
return storedValue
}
operator fun setValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>, value: String) {
storedValue = value
}
}
class Example {
var name: String by ExampleDelegate()
}
This code defines a custom delegate that stores and retrieves a string value for a property.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Each time the property
nameis accessed or updated, the delegate'sgetValueorsetValuefunction runs. - How many times: Once per property access or update; no loops or recursion inside these functions.
Each property access or update runs a simple function that does a single assignment or return.
| Number of Accesses (n) | Approx. Operations |
|---|---|
| 10 | 10 simple get or set calls |
| 100 | 100 simple get or set calls |
| 1000 | 1000 simple get or set calls |
Pattern observation: The time grows directly with the number of property accesses or updates, each costing about the same.
Time Complexity: O(n)
This means the total time grows linearly with how many times you get or set the property.
[X] Wrong: "Using a custom delegate makes property access slower in a way that depends on the size of stored data inside the delegate."
[OK] Correct: The delegate functions here do simple operations that take constant time regardless of stored data size, so each access or update costs about the same.
Understanding how custom delegates work and their time cost helps you explain your code clearly and reason about performance in real projects.
What if the delegate stored data in a list and searched it on each get? How would the time complexity change?
Practice
custom delegated properties in Kotlin?Solution
Step 1: Understand property delegation concept
Delegated properties let you customize how a property's value is handled behind the scenes.Step 2: Identify the purpose of custom delegation
Custom delegated properties specifically allow control over getting and setting property values.Final Answer:
To control how a property's value is stored and retrieved -> Option CQuick Check:
Custom delegation = control property access [OK]
- Confusing delegation with constructors
- Thinking delegation defines functions
- Mixing delegation with method overriding
Solution
Step 1: Recall Kotlin delegation syntax
Delegated properties use thebykeyword followed by a delegate instance.Step 2: Match correct syntax
val prop by Delegate()correctly declares a delegated property.Final Answer:
val prop by Delegate() -> Option BQuick Check:
Delegation uses 'by' keyword [OK]
- Using '=' instead of 'by' for delegation
- Incorrect delegate type declaration
- Missing parentheses for delegate constructor
class Delegate {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): String {
return "Hello from delegate"
}
}
class Example {
val message: String by Delegate()
}
fun main() {
val e = Example()
println(e.message)
}Solution
Step 1: Understand getValue operator
ThegetValuefunction returns the string "Hello from delegate" when the property is accessed.Step 2: Trace property access in main()
Accessinge.messagecallsgetValueand prints the returned string.Final Answer:
Hello from delegate -> Option AQuick Check:
Delegate getValue returns string [OK]
- Expecting default property value instead of delegate's
- Confusing getValue with setValue
- Assuming compilation error due to missing parameters
class Delegate {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): Int {
return 42
}
}
class Example {
var number: Int by Delegate()
}
fun main() {
val e = Example()
e.number = 10
println(e.number)
}Solution
Step 1: Check property mutability and delegation
The propertynumberisvar, so delegate must support both get and set.Step 2: Verify delegate methods
TheDelegateclass only definesgetValue, missingsetValueneeded forvar.Final Answer:
Delegate class lacks setValue operator function -> Option DQuick Check:
var needs getValue and setValue [OK]
- Forgetting setValue for var properties
- Assuming getValue return type must be String
- Thinking delegate must be interface
class LoggingDelegate<T>(var value: T) {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): T {
println("Getting value of ${property.name}")
return value
}
operator fun setValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>, newValue: T) {
println("Setting value of ${property.name} to $newValue")
value = newValue
}
}
class Example {
var data: String by LoggingDelegate("initial")
}
fun main() {
val e = Example()
e.data = "new"
println(e.data)
}Solution
Step 1: Analyze delegate methods
The delegate definesgetValueandsetValuewith print statements logging property access.Step 2: Trace main function output
Settinge.data = "new"prints setting log, then printinge.datatriggers get log and prints value.Final Answer:
Logs on get and set, prints 'Setting value of data to new' then 'Getting value of data' and 'new' -> Option AQuick Check:
Delegate logs on get/set correctly [OK]
- Missing setValue causes no set logging
- Assuming delegate must be non-generic
- Forgetting to pass initial value to delegate
Ready to prove it?
Pass the test and this pattern moves unknown
