Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

156
Visualizações
Cómo actualizar la clase de datos de Kotlin con propiedades de una clase de datos diferente

Si tengo por ejemplo una entidad:

 data class SampleEntity( val a: Int, val b: Int, val c: Int, val d: Int){ fun update(form: SampleEntityUpdateForm): SampleEntity{ ... return this SampleEntity updated with form } }

y un formulario para actualizar esta entidad:

 data class SampleEntityUpdateForm( val a: Int?, val b: Int?, val c: Int?, val d: Int? )

¿Cuál es la mejor manera de actualizar la entidad con este formulario (es decir, implementar SampleEntity.update(...)), dejando las propiedades que son nulas en SampleEntityUpdateForm como estaban en la entidad original, con una placa de caldera mínima.

Así por ejemplo:

 val sampleEntityInst = SampleEntity(1,2,3,4) val sampleEntityUpdateForm(b = 20, d = 40) val updatedSampleEntityInst = sampleEntityInst.update(sampleEntityUpdateForm)

donde actualizadoSampleEntityInst será igual a SampleEntity(1,20,3,40).

obviamente podría implementar SampleEntity.update como:

 fun update(form: SampleEntityUpdateForm) = SampleEntity( a = form.a ?: this.a, b = form.b ?: this.b, c = form.c ?: this.c, d = form.d ?: this.d, )

Pero esto tiene un poco de repetición/repetición. ¿Hay algo ya hecho para permitir hacer esto con menos repetición/placa de caldera?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Compruebe el método de copia disponible en todas las clases de datos, por ejemplo:

 data class SampleEntity( val a: Int, val b: Int, val c: Int, val d: Int){ fun update(form: SampleEntityUpdateForm): SampleEntity{ return this.copy(a = form.a, b = form.b, ...) } }

Editar : me perdí el giro de nulabilidad. El uso de la función magic a continuación funciona, pero en mi opinión, el enfoque directo tiene una mejor ergonomía.

Puede haber casos de uso en los que la reflexión esté bien: una gran cantidad de propiedades, una transformación complicada de los parámetros entrantes, etc.

 fun main() { val sampleEntityForm = SampleEntityUpdateForm(a = null, b = 20, c = null, d = 40) val sampleEntityInst = SampleEntity(1, 2, 3, 4) magic(sampleEntityForm, sampleEntityInst).also { println(it) } // prints: SampleEntity(a=1, b=20, c=3, d=40) } fun magic(from: SampleEntityUpdateForm, using: SampleEntity): SampleEntity { val fromValues = from::class.members.filterIsInstance<KProperty1<SampleEntityUpdateForm, Int?>>().map { it.get(from) } val usingValues = using::class.members.filterIsInstance<KProperty1<SampleEntity, Int>>().map { it.get(using) } val nullsEliminated = usingValues.mapIndexed { i, value -> fromValues[i] ?: value }.toTypedArray() return SampleEntity::class.primaryConstructor!!.call(*nullsEliminated) }
over 4 years ago · Santiago Trujillo Relatório

0

Este es el problema con la escritura estática. El modelo y la repetitividad vienen incorporados. Creo que tu ejemplo con a = form.a ?: this.a es una buena solución. Al usar un lenguaje escrito estáticamente como Kotlin, es mejor aceptar el modelo estándar y seguir adelante.

Si quieres ser más elegante, tienes que usar algo más dinámico. Por ejemplo, puede utilizar JSON, que es más flexible. Esta solución utiliza JsonMergePatch de JSON-P para crear un parche y aplicarlo a su objeto. Estoy usando Jackson para convertir entre objetos POJO y JSON a través de la reflexión.

Este método tiene la ventaja de poder establecer valores en null a través del parche también. Si el valor en el parche es null , establece el valor de destino en null . Si el valor no está en el parche, se conserva el valor existente. Esto es algo que no puedes hacer muy bien de forma nativa; tienes que empezar a volverte loco con cosas como nullable Optional s.

 fun main() { val original = SampleEntity(a = 0, b = 0, c = 0, d = 0) val patch = Json.createObjectBuilder() .add("b", 2) .add("d", 4) .build().let { Json.createMergePatch(it) } val patched: SampleEntity = original.update(patch) println(patched) } data class SampleEntity( val a: Int, val b: Int, val c: Int, val d: Int ) { fun update(patch: JsonMergePatch): SampleEntity { val jsonValue = objectMapper.convertValue<JsonValue>(this) val patched = patch.apply(jsonValue) return objectMapper.convertValue(patched) } companion object { private val objectMapper: ObjectMapper = ObjectMapper() .registerKotlinModule() .registerModule(JSONPModule()) } }

Producción:

 SampleEntity(a=0, b=2, c=0, d=4)

Dependencias:

 dependencies { implementation("jakarta.json", "jakarta.json-api", "2.0.1") implementation("org.glassfish", "jakarta.json", "2.0.1") implementation("com.fasterxml.jackson.core", "jackson-core", "2.13.0") implementation("com.fasterxml.jackson.datatype", "jackson-datatype-jakarta-jsonp", "2.12.2") implementation("com.fasterxml.jackson.module", "jackson-module-kotlin", "2.13.0") }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda