Котлин — Сравнение значений между общими полями двух классов

#kotlin

#котлин

Вопрос:

У меня есть два класса, которые имеют почти все одинаковые свойства.

 data class UserDetailsDTO( username: String?, id: UUID, lastName: String? ..) data class UserDetailsInput( username: String?, id: UUID, lastName: String?..)  

И у меня есть две переменные одного и того же класса с заполненными свойствами.

 val result = method that returns type UserDetailsDTO  val update = UserDetailsInput type  

Мне нужно это сделать:

сравните обновление с результатом, сохраните в обновлении только те поля, которые отличаются от результата и не являются нулевыми.

Как я могу этого достичь ? Я был бы признателен за любое руководство.

Комментарии:

1. Как насчет полей в UserDetailsInput, которые не существуют в UserDetailsDТО, должны ли они также быть возвращены?

2. keep only the fields in update that are different from result and not null. А как насчет тех, которые ничем не отличаются? Они должны стать нулевыми? Кроме того, вы используете ненулевые типы в UserDetailsDTO, поэтому они никогда не будут пустыми.

3. @lukas.j в текущей реализации таких полей нет (потому что одно из них является выводом полей в базе данных, другое-вводом для изменения некоторых из этих полей) , но если бы они были, они должны быть возвращены да.

4. @ArpitShukla Все они могут быть аннулированы. Я написал это здесь неправильно. Те, чьи значения одинаковы, должны быть пропущены. Пример: Входное имя пользователя отличается от имени пользователя результата, сохраните его в конечной переменной. Введенная фамилия совпадает с фамилией результата, пропустите это. входная категория равна нулю, пропустите это.

5. Что вы подразумеваете под skip этим «здесь»? Какой тип данных вам нужен в конце для получения результата?

Ответ №1:

Вы можете создать служебный метод, взять их обоих и вернуть UserDetailsDTO только с разницей

(Я никогда не делал котлин, но я думаю, что это что-то в этом роде )

 Class TestDTO(){    public String name;    public Int age;   }  Class TestInput(){    public String name;    public Int age;   }   fun TestDiff(testDTO: TestDTO,testInput : TestInput ){    finalDTO = new TestDTO();    if(testInput.name != null amp;amp; testInput.name != testDTO.name){  finalDTO.name = testInput.name;  }    if(testInput.age != null amp;amp; testInput.age != testDTO.age){  finalDTO.age = testInput.age;  }    return finalDTO; }   

Ответ №2:

Вы можете создать функцию расширения, подобную этой:

 fun UserDetailsInput.uniqueValue(UserDetailsDTO: UserDetailsInput) {  id = if (id != UserDetailsDTO.id) UserDetailsDTO.id else id  username = if (username != UserDetailsDTO.username) UserDetailsDTO.username else username  lastName = if (lastName != UserDetailsDTO.lastName) UserDetailsDTO.lastName else lastName  }  

Комментарии:

1. Спасибо! Должен ли я проверять каждое поле ввода или есть общий способ проверить все ? Поскольку существует 9-10 полей, я добавил только два в приведенном выше примере, чтобы абстрагироваться от проблемы

Ответ №3:

Не очень элегантно. Использует отражение, чтобы проверить, какое поле UserDetailsInput существует также в целевом классе UserDetailsDTO:

 import java.util.* import kotlin.reflect.full.memberProperties  data class UserDetailsDTO(  val username: String?,  val id: UUID,  val lastName: String? )  data class UserDetailsInput(  val username: String?,  val id: UUID,  val lastName: String?,  val firstName: String? )  val result = UserDetailsDTO("User 1", UUID.randomUUID(), "Abc") val input = UserDetailsInput("User 1", result.id, null, "Super")  val mapOfDifferenValues = mutableMapOflt;String, Any?gt;()  val propsInResult = UserDetailsDTO::class.memberProperties val propsInInput = UserDetailsInput::class.memberProperties  for (propInInput in propsInInput) {  // Value from Input  val valueFromInput = propInInput.get(input)  // Check if it is not null  if (valueFromInput != null) {  // Check if a field with same name exists in 'result' class  if (propInInput.name in propsInResult.map { it.name }) {  // A field with same name exists in result class, so check if it has the same value  if (valueFromInput != propsInResult.first { it.name == propInInput.name }.get(result)) {  // It does not have the same value, so add it to the map  mapOfDifferenValues[propInInput.name] = valueFromInput  }  } else {  // There is no field with the same name in 'result' class, so add it to the map  mapOfDifferenValues[propInInput.name] = valueFromInput  }  } }  println(mapOfDifferenValues)