java - 有没有一种方法可以有效地比较任意对象的字段

标签 java kotlin

目前,如果我需要通过特定字段比较对象,我会实现 DiffEqual 接口(interface)

interface DiffEquals<T> {
  fun isItemSame(other: Any?): Boolean
  fun isContentSame(other: Any?): Boolean
}

某个对象

data class Book(
  val title: String, val amount: String, var isSelected: Boolean = false
) : DiffEquals {

  override fun isItemSame(other: Any?): Boolean {
    if (other != null && other is Book) {
      if (title != other.title) {
        return false
      }
      return true
    } else {
      return false
    }
  }

  override fun isContentSame(other: Any?): Boolean {
    other as Book
    if (amount != other.amount) return false
    if (isSelected != other.isSelected) return false

    return true
  }
}

我不喜欢这种方法,因为它需要大量的虚拟代码。我尝试制作Id1、Id2、Id3、Mutable1、Mutable2、Mutable3等注释,但资源消耗很大,因此我不得不回滚到上面的界面。如何实现一种比较指定字段的通用比较机制? (不是标准的 equals 不适合,因为更复杂的对象具有不断变化的字段,但对于相等并不重要,重写 equals 会与虚拟代码产生相同的问题,并且在大多数情况下,我需要完全等于)

最佳答案

您可以创建内联 equalsBy 函数:

@PublishedApi
@Suppress("UNCHECKED_CAST")
internal inline fun <T> T.eqlBy(other: Any?, prop1: T.() -> Any?): Boolean = prop1() == (other as T).prop1()

inline fun <reified T> T.equalsBy(other: Any?, prop1: T.() -> Any?): Boolean =
    other is T && eqlBy(other, prop1)

inline fun <reified T> T.equalsBy(other: Any?, prop1: T.() -> Any?, prop2: T.() -> Any?): Boolean =
    equalsBy(other, prop1) && eqlBy(other, prop2)

inline fun <reified T> T.equalsBy(other: Any?, prop1: T.() -> Any?, prop2: T.() -> Any?, prop3: T.() -> Any?): Boolean =
    equalsBy(other, prop1, prop2) && eqlBy(other, prop3)

像这样使用它们:

data class Book(
    val title: String, val amount: String, var isSelected: Boolean = false
) : DiffEquals<Book> {
    override fun isItemSame(other: Book) = equalsBy(other) { title }
    override fun isContentSame(other: Book) = equalsBy(other, { amount }, { isSelected })
}

关于java - 有没有一种方法可以有效地比较任意对象的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59479947/

相关文章:

android - 数据绑定(bind)时如何将整数转换为 float ?

java - 如何在 Webflux 功能端点测试中禁用 Spring Security

java - 如何在TextArea中创建粗体打印?

kotlin - 用字符串中的多个字符替换多个字符

kotlin - Kotlin协程 future 等待超时(不取消)

java - 使用 Jackson 反序列化可选多态字段

java - Spring:从哪里获取ApplicationContext?

java - for循环得到错误 "illegal start of type"

java - 区分 Java 和 C 中的 "static"

kotlin - 为什么 “repeat”函数在kotlin中可以取消