【问题标题】:How to compare two arrays in Kotlin?如何比较 Kotlin 中的两个数组?
【发布时间】:2016-02-08 15:05:01
【问题描述】:

给定 Kotlin 中的一些数组

let a = arrayOf("first", "second")
val b = arrayOf("first", "second")
val c = arrayOf("1st", "2nd")

Kotlin 标准库中是否有内置函数可以测试两个数组的每个元素的(值)相等性?

因此导致:

a.equals(b) // true
a.equals(c) // false

equals() 在这两种情况下实际上都返回了false,但也许 Kotlin 有可以使用的内置函数?

有静态函数java.utils.Arrays.deepEquals(a.toTypedArray(), b.toTypedArray()),但我更喜欢实例方法,因为它可以更好地与可选项一起使用。

【问题讨论】:

  • 这可能是扩展函数的情况。

标签: arrays equals kotlin


【解决方案1】:

在 Kotlin 1.1 中,您可以使用 contentEqualscontentDeepEquals 来比较两个数组的结构相等性。例如:

a contentEquals b // true
b contentEquals c // false

在 Kotlin 1.0 中,没有“Kotlin 标准库的内置函数来测试两个数组的每个元素的(值)相等性。”

“数组总是使用equals() 进行比较,就像所有其他对象一样”(Feedback Request: Limitations on Data Classes | Kotlin Blog)。

所以a.equals(b) 只会在ab 引用同一个数组时返回true

但是,您可以使用extension functions 创建自己的“可选”友好方法。例如:

fun Array<*>.equalsArray(other: Array<*>) = Arrays.equals(this, other)
fun Array<*>.deepEqualsArray(other: Array<*>) = Arrays.deepEquals(this, other)

附: Feedback Request: Limitations on Data Classes | Kotlin Blog 上的 cmets 也值得一读,特别是 comment 39364

【讨论】:

    【解决方案2】:

    Kotlin 1.1 引入了按内容比较数组的扩展: contentEqualscontentDeepEquals

    这些扩展是中缀,所以你可以通过以下方式使用它们:

    val areEqual = arr1 contentEquals arr2
    

    【讨论】:

      【解决方案3】:

      在 koltin 中,如果您的数组或 ArrayList 是 data Class 您可以简单地比较 array :aarray :b

      喜欢这个

      if(a == b)

      如果它匹配两个数组的所有值,它将返回简单的布尔值,但如果你匹配的不是数据 data Class 那么你可以使用这个扩展来将它与单个值进行比较

      fun <T> Array<T>.isEqual(comparable: Array<T>): Boolean {
          var isChanged = true
      
          if (this.size == comparable.size) {
              for (index in 0 until comparable.size) {
                  if (this[index] != comparable[index]) {
                      isChanged = false
                      break
                  }
              }
          } else {
              isChanged = false
          }
      
          return isChanged
      }
      

      那么你就可以使用你的数组了

          val a = arrayOf("first", "second")
          val b = arrayOf("first", "second")
      
          println(a.isEqual(b)) //true
      
          a[0] = "third"
      
          println(a.isEqual(b)) //false
      

      【讨论】:

      • 你把这个函数保存在哪里以备将来重复使用? Github 仓库?
      【解决方案4】:

      如果你想比较两个Collections的内容忽略顺序你可以添加这个简单的扩展:

      infix fun <T> Collection<T>.sameContentWith(collection: Collection<T>?)
          = collection?.let { this.size == it.size && this.containsAll(it) }
      

      ...并像这样使用它:

      a = mutableListOf<String>()
      b = mutableListOf<String>()
      
      isListsHasSameContent = a sameContentWith b
      

      【讨论】:

      • 太棒了。这应该是收集的公认答案(如果不使用数组)
      • 注意边缘状况; listOf("a", "b", "b").sameContentWith(listOf("a", "a", "b")) 在预期返回 false 时为 true。
      【解决方案5】:

      对于一个简单的等号(不是深度等号!):

      otherArray.size == array.size && otherArray.filter { !array.contains(it) }.isEmpty()
      

      此代码将比较大小和项目。项目与.equals()比较。

      【讨论】:

      • 这里不考虑数组的顺序;但是一般的方法对 Sets 有好处。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 2019-12-07
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多