Replacing stream collection in native Kotlin solution
I am currently using a Kotlin function to extract a map from a Json structure with key value pairs.
The JSON used to build the map contains a label and a value:
"values": [
{
"label": "Email",
"value": "email"
},
{
"label": "Social media",
"value": "socialMedia"
},
{
"label": "Word of mouth",
"value": "wordOfMouth"
},
{
"label": "Newspaper",
"value": "newspaper"
}
],
The "JSON tag" should be the key to the map and the value "value".
This is the code used to retrieve and convert JSON to a map using the Java 8 stream collect method.
fun extractValue(jsonNode: JsonNode?): Map<String, String> {
val valuesNode = jsonNode?.get("values") ?: mapper.createArrayNode()
return valuesNode.map { Pair(it.get("label")?.asText() ?: "", it.get("value")?.asText() ?: "") }
.stream().collect({ HashMap<String, String>()}, { m, p -> m.put(p.first, p.second) } , { m, p -> })
}
How do you write the part with stream (). Going to idiomatic Kotlin? What alternatives do you need to replace
flow(). Collect()
in this particular case?
source to share
So you have a list of pairs and you want to convert it to a map? You can just replace .stream().collect(...)
with Kotlin toMap()
. From the Kotlin docs:
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
Returns a new map containing all key-value pairs from the given collection of pairs.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html
source to share
the associateBy method is similar to java Collectors#toMap
, so you can just do it in kotlin like below:
fun extractValue(jsonNode: JsonNode?): Map<String, String> {
// key mapping ---v
return jsonNode?.get("values")?.associateBy({ it.get("label")?.asText()?:"" }){
it.get("value")?.asText() ?: "" // value mapping
} ?: emptyMap()
// ^--- default value is an empty map
}
source to share