How can I rewrite this code without having to resort to a MutableMap and conversion to immutable map?
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val map = mutableMapOf("key1" to mandatoryValue)
optionalValue?.let { map.put("key2", it) }
return map.toMap()
}
My alternative solution isn't very nice either because it needs an unsafe cast:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf(
"key1" to mandatoryValue,
"key2" to optionalValue
).filterValues { it != null } as Map<String, String>
What I am looking for is something in the lines of:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf(
"key1" to mandatoryValue,
optionalValue?.let { "key2" to it }
)
toMap()
does not necessarily create an immutable map. It is only guaranteed to be read-only. The underlying class instance might be a MutableMap (which in the current implementation is true if it has more than one key). Therefore, toMap()
in your first block of code is unnecessary. The MutableMap is automatically upcast to Map when you return it since you specified Map as the return type. So, you could have put
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val map = mutableMapOf("key1" to mandatoryValue)
optionalValue?.let { map.put("key2", it) }
return map
}
or
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mutableMapOf("key1" to mandatoryValue).apply {
if (optionalValue != null) put("key2", optionalValue)
}
To get the syntax you requested in your last example, you could create an overload of mapOf
that accepts and filters null values:
fun <K, V> mapOf(vararg pairs: Pair<K, V>?): Map<K, V> =
mapOf(*pairs.filterNotNull().toTypedArray())
You can have your own extension function as follows and then use it to filter null values from a Map
:
fun <K, V> Map<K, V?>.filterValuesNotNull() =
mapNotNull { (k, v) -> v?.let { k to v } }.toMap()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With