有没有一种方法可以有效比较野蛮物体的场

时间:2019-12-25 15:59:43

标签: java kotlin

当前,如果我需要按特定字段比较对象,则可以实现DiffEqual接口

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之类的注释,但是这很耗资源,因此我不得不回滚到上面的接口。如何实现一种比较指定字段的通用比较机制? (非标准的等值项不适合,因为更复杂的对象的字段会不断变化,但对等项并不重要,重写等号会导致伪代码出现相同的问题,并且在大多数情况下,我需要完全等号)

2 个答案:

答案 0 :(得分:1)

您可以创建inline 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 })
}

答案 1 :(得分:0)

使用varargs对@Bananon答案进行轻微警告

inline fun <reified T> T.equalTo(other: Any?, vararg properties: T.() -> Any?): Boolean {
  if (other !is T) return false
  properties.forEach {
    if (it.invoke(this) != it.invoke(other)) {
      return false
    }
  }
  return true
}
相关问题