kotlinintermediate
Map Delegation for Dynamic Properties
Delegate properties to maps: dynamic configuration, JSON-to-object mapping, and flexible data classes.
kotlinPress ⌘/Ctrl + Shift + C to copy
class Config(private val map: Map<String, Any?>) {
val host: String by map
val port: Int by map
val debug: Boolean by map
val name: String by map
override fun toString() = "Config(host=$host, port=$port, debug=$debug, name=$name)"
}
// Mutable map delegation
class MutableConfig(private val map: MutableMap<String, Any?>) {
var host: String by map
var port: Int by map
var debug: Boolean by map
fun toMap(): Map<String, Any?> = map.toMap()
override fun toString() = map.toString()
}
// JSON-like object
class JsonObject(private val data: MutableMap<String, Any?> = mutableMapOf()) {
var name: String? by data
var age: Int? by data
var email: String? by data
var active: Boolean? by data
fun raw() = data.toMap()
fun has(key: String) = data.containsKey(key)
companion object {
fun from(vararg pairs: Pair<String, Any?>) = JsonObject(mutableMapOf(*pairs))
}
}
// Environment-backed config
class EnvConfig {
private val env = System.getenv().toMutableMap().apply {
// Defaults for demo
putIfAbsent("APP_HOST", "localhost")
putIfAbsent("APP_PORT", "8080")
putIfAbsent("APP_DEBUG", "false")
}
private val prefixed = env
.filterKeys { it.startsWith("APP_") }
.mapKeys { (k, _) -> k.removePrefix("APP_").lowercase() }
val host: String by prefixed
val port: String by prefixed
val debug: String by prefixed
}
// Nested map delegation
class DatabaseConfig(config: Map<String, Any?>) {
val url: String by config
val username: String by config
val password: String by config
val poolSize: Int by config
}
class AppConfig(raw: Map<String, Any?>) {
val appName: String = raw["appName"] as? String ?: "MyApp"
val database = DatabaseConfig(
@Suppress("UNCHECKED_CAST")
(raw["database"] as? Map<String, Any?>) ?: emptyMap()
)
}
fun main() {
// Read-only config
val config = Config(mapOf(
"host" to "localhost",
"port" to 8080,
"debug" to true,
"name" to "MyApp"
))
println("Config: $config")
println("Host: ${config.host}, Port: ${config.port}")
// Mutable config
val mutable = MutableConfig(mutableMapOf(
"host" to "0.0.0.0",
"port" to 3000,
"debug" to false
))
println("\nBefore: $mutable")
mutable.host = "localhost"
mutable.debug = true
println("After: $mutable")
println("Raw: ${mutable.toMap()}")
// JSON-like
val json = JsonObject.from(
"name" to "Alice",
"age" to 30,
"email" to "alice@test.com"
)
println("\nJSON name: ${json.name}")
json.active = true
println("Raw: ${json.raw()}")
// Env config
val env = EnvConfig()
println("\nEnv host: ${env.host}")
println("Env port: ${env.port}")
// Nested config
val appConfig = AppConfig(mapOf(
"appName" to "Production App",
"database" to mapOf(
"url" to "jdbc:postgresql://localhost/db",
"username" to "admin",
"password" to "secret",
"poolSize" to 10
)
))
println("\nApp: ${appConfig.appName}")
println("DB: ${appConfig.database.url} (pool: ${appConfig.database.poolSize})")
}Use Cases
- Dynamic configuration loading
- JSON to typed object mapping
- Environment variable binding
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinbeginner
Delegate Properties to a Map
Store class properties in a map using Kotlin delegation for dynamic and flexible data objects.
Best for: Dynamic configuration from external sources
#kotlin#delegation
kotlinintermediate
Delegation — by, lazy, observable, and Custom
Use Kotlin delegation for reusable behavior: by keyword, lazy, observable, vetoable, and map-backed.
Best for: Composing behavior without deep inheritance
#kotlin#delegation
kotlinintermediate
Interface Delegation with 'by'
Delegate interface implementations with the 'by' keyword: composition over inheritance patterns.
Best for: Composition over inheritance
#kotlin#delegation
kotlinintermediate
Map Operations — Transform, Merge, Group
Advanced map operations: groupBy, associate, flatMap, merge strategies, and map transformations.
Best for: Data aggregation and grouping
#kotlin#collections