Gul*_*han 12 dictionary object kotlin
有没有简单的方法或任何标准的库方法来通过属性名称将Kotlin数据类对象转换为它的属性的地图/字典?可以避免反思吗?
Ken*_*ing 14
这个扩展函数使用反射,但也许它会帮助像我这样的人在未来遇到这个:
inline fun <reified T : Any> T.asMap() : Map<String, Any?> {
val props = T::class.memberProperties.associateBy { it.name }
return props.keys.associateWith { props[it]?.get(this) }
}
Run Code Online (Sandbox Code Playgroud)
abg*_*UNG 10
我今天有相同的用例进行测试,最后我用Jackson对象映射器将Kotlin数据类转换为Map.在我的案例中,运行时性能不是一个大问题.我没有检查细节,但我相信它是在引擎盖下使用反射,但这是在幕后发生的事情.
例如,
val dataclass = DataClass(p1 = 1, p2 = 2)
val dataclassAsMap = objectMapper.convertValue(dataclass, object:
TypeReference<Map<String, Any>>() {})
//expect dataclassAsMap == mapOf("p1" to 1, "p2" to 2)
Run Code Online (Sandbox Code Playgroud)
我使用的是jackson方法,但事实证明,此方法在Android上的首次序列化(在github问题上)非常糟糕。对于较旧的android版本,它的情况更糟,(请参阅此处的基准)
但是使用Gson,您可以更快地完成此操作。双向转换如下所示:
val gson = Gson()
//convert a data class to a map
fun <T> T.serializeToMap(): Map<String, Any> {
return convert()
}
//convert a map to a data class
inline fun <reified T> Map<String, Any>.toDataClass(): T {
return convert()
}
//convert an object of type I to type O
inline fun <I, reified O> I.convert(): O {
val json = gson.toJson(this)
return gson.fromJson(json, object : TypeToken<O>() {}.type)
}
Run Code Online (Sandbox Code Playgroud)
kotlinx.serialization有一个实验性的Properties格式,这使得将 Kotlin 类转换为映射变得非常简单,反之亦然:
@ExperimentalSerializationApi
@kotlinx.serialization.Serializable
data class Category constructor(
val id: Int,
val name: String,
val icon: String,
val numItems: Long
) {
// the map representation of this class
val asMap: Map<String, Any> by lazy { Properties.encodeToMap(this) }
companion object {
// factory to create Category from a map
fun from(map: Map<String, Any>): Category =
Properties.decodeFromMap(map)
}
}
Run Code Online (Sandbox Code Playgroud)
您可以获得的最接近的是存储在映射中的委托属性。
示例(来自链接):
class User(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
Run Code Online (Sandbox Code Playgroud)
然而,将其与数据类一起使用可能效果不太好。
| 归档时间: |
|
| 查看次数: |
8347 次 |
| 最近记录: |