Java 将地图转换为数据类

Java 将地图转换为数据类,java,kotlin,Java,Kotlin,Kotlin中是否有一个简单的方法允许我将映射转换为任意数据类 我试图转换的映射具有数据类所需字段的所有键 我四处寻找,但没有找到任何关于以一种非常普通的方式进行这项工作的说法 我知道我可以使用ObjectMapper,但这需要一个额外的库。寻找只需Kotlin就可以使用的东西。也许是适合你的东西。这样你也可以调整地图。但是,这也允许添加不可1:1映射到类属性的键和值,例如: class YourData { val backedMap = mutableMapOf<String,

Kotlin中是否有一个简单的方法允许我将映射转换为任意数据类

我试图转换的映射具有数据类所需字段的所有键

我四处寻找,但没有找到任何关于以一种非常普通的方式进行这项工作的说法

我知道我可以使用
ObjectMapper
,但这需要一个额外的库。寻找只需Kotlin就可以使用的东西。

也许是适合你的东西。这样你也可以调整地图。但是,这也允许添加不可1:1映射到类属性的键和值,例如:

class YourData { 
  val backedMap = mutableMapOf<String, String>()
  var someProp by backedMap
}

val obj = YourData().apply {
    someProp = "value"
}
但另一方面,可以使用相同的地图自动填充字段:

val sourceMap = mutableMapOf("someProp" to "newValue") // the map you want to use to automatically fill up your data class
sourceMap.forEach { key, newValue -> obj.backedMap[key] = newValue }
另一种方法是“仅仅”使用反射。这样,您可以省略背景映射,而只扫描属性,例如:

YourData::class.memberProperties.asSequence()
                                .filterIsInstance<KMutableProperty<*>>()
                                .filter { it.name in sourceMap.keys }
                                .forEach { prop ->
                                  prop.setter.call(obj, sourceMap[prop.name])
                                }
YourData::class.memberProperties.asSequence()
.filterIsInstance()
.filter{sourceMap.keys中的it.name}
.forEach{prop->
prop.setter.call(obj,sourceMap[prop.name])
}

为什么不直接使用映射委托

class MyData(val map: Map<String, String>) {
    val foo by map
    val bar by map
}

使用kotlin反射将构造函数参数映射到值 此泛型函数适用于在主构造函数中接收字段数据的任何类

与firebase等JSON数据库配合良好,并使用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)
}
像这样使用

mapToObject(map, Person::class)

不幸的是,kotlin reflect不是标准kotlin库的一部分。(单独下载)是的,你说得对。它需要
kotlin reflect
。不知何故,我认为您不想使用
ObjectMapper
,但实际上您编写了不想使用附加库的代码。我的错误。我还是会把它留在这里的。谢谢。尽管它增加了一些东西,但这是一个很好的例子。这是我倾向于的一个可能的选择,尽管问题是我更喜欢让类成为常规数据类。这项工作的主要目标是,它将进入一个通用函数,该函数生成一个映射(来自服务调用),然后以通用方式将其映射到类。对其进行了更新,使其也可以是一个数据类。我将此标记为一个答案,因为我认为它最接近我所寻找的,而无需使用
kotlin reflect
。不过最后,我还是选择了ObjectMapper。哦,天哪,这很有魅力。我尝试过如何从gson
LinkedTreeMap
映射到我的自定义数据类,这太棒了。@Dio Lantief Widoyoko,gson内置了这个功能
gson.fromJson(jsonObject,YourType::class.java)
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)
}
data class Person(val firs: String, val last: String)
mapToObject(map, Person::class)