Is there an easy method in Kotlin to allow me to convert a Map to an arbitrary data class?
The Map I'm trying to convert has all of the keys of the required fields of the data class.
I've hunted around, but haven't been able to find anything that seems to talk about doing this in a very generic way.
I know that I can use ObjectMapper
, but that requires an extra library. Looking for something that is available just with Kotlin.
Data class is a simple class which is used to hold data/state and contains standard functionality. A data keyword is used to declare a class as a data class.
To define a class in Kotlin, class keyword is used: class ClassName { // property // member function ... .. ... } Here, we defined a class named Lamp . The class has one property isOn (defined in same way as variable), and two member functions turnOn() and turnOff() .
Kotlin map is a collection that contains pairs of objects. Map holds the data in the form of pairs which consists of a key and a value. Map keys are unique and the map holds only one value for each key. Kotlin distinguishes between immutable and mutable maps.
The first and most standard way of creating a map in Kotlin is by using mapOf . mapOf creates an immutable map of the key-value pairs we provide as parameters. Since the map is immutable, we won't find methods like put , remove or any other modifying functions.
Why not just use a map delegate?
class MyData(val map: Map<String, String>) {
val foo by map
val bar by map
}
Or you can wrap it using a companion object and call it using MyData.from(mymap)
data class MyData(val foo: String, val bar: String) {
companion object {
fun from(map: Map<String, String>) = object {
val foo by map
val bar by map
val data = MyData(foo, bar)
}.data
}
using kotlin reflection to map constructor parameters to map values this generic function will work for any class that receives field data in the primary constructor
Works well with JSON dbs like firebase and was tested with Map objects from Firebase DocumentSnapshot.data
fun <T : Any> mapToObject(map: Map<String, Any>, clazz: KClass<T>) : T {
//Get default constructor
val constructor = clazz.constructors.first()
//Map constructor parameters to map values
val args = constructor
.parameters
.map { it to map.get(it.name) }
.toMap()
//return object from constructor call
return constructor.callBy(args)
}
with some class
data class Person(val firs: String, val last: String)
use like this
mapToObject(map, Person::class)
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