同じタイプの2つのリストを比較するために、kotlin equals 関数に出会いました。データクラスを使用した純粋なKotlinで正常に動作します。
KotlinプロジェクトでJavaライブラリを使用しています。このライブラリでは、コールバックメソッドがX秒の時間間隔でオブジェクトのリストを返します。すべての呼び出しで古いリストと新しいリストを比較しようしかし、アイテムが同じで等しい場合でも、equalsはfalseを返します。
val mOldList: MutableList<MyObject>()? = null
override fun updatedList(list: MutableList<MyObject>){
// other code
if (mOldList.equals(list)) // false everytime
}
これは、ライブラリのJavaのequalsメソッドによるものですか?
リスト比較の代替案は評価に値します。
Javaリストはequals
メソッドを実装し、2つのリストが同じ順序で同じ要素を含む場合、等しいと定義されます。 equals
クラスにMyObject
メソッドがありません。
配列とcontentDeepEquals
を使用できます。
infix fun <T> Array<out T>.contentDeepEquals(
other: Array<out T>
): Boolean
JVM
1.1
@JvmName("contentDeepEqualsInline") infix fun <T> Array<out T>.contentDeepEquals(
other: Array<out T>
): Boolean
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/content-deep-equals.html
Zip を使用する
Zip
は、この配列の要素と同じインデックスを持つ他の配列から構築されたペアのリストを返します。返されるリストには、最短のコレクションの長さがあります。
fun listsEqual(list1: List<Any>, list2: List<Any>): Boolean {
if (list1.size != list2.size)
return false
val pairList = list1.Zip(list2)
return pairList.all { (elt1, elt2) ->
elt1 == elt2
}
}
ただfyiを呼び出すことができますlist1 == list2
は、カスタムオブジェクトがdata class
(自動的にequalsをオーバーライドします)。
1つのリストを反復処理し、2番目のリストから対応する位置の値を確認できます。以下の例を参考にしてください。
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
list1.forEachIndexed { i, value ->
if (list2[i] == value)
{
// your implementaion
}
}
さらに、変更された値のリストをフィルタリングできます。
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
val changedList = list1.filterIndexed { i, value ->
list2[i] != value)
}
以下の実装を使用して、2つのCollection
を比較できます。
infix fun <T> Collection<T>.deepEqualTo(other: Collection<T>): Boolean {
// check collections aren't same
if (this !== other) {
// fast check of sizes
if (this.size != other.size) return false
val areNotEqual = this.asSequence()
.Zip(other.asSequence())
// check this and other contains same elements at position
.map { (fromThis, fromOther) -> fromThis == fromOther }
// searching for first negative answer
.contains(false)
if (areNotEqual) return false
}
// collections are same or they are contains same elements with same order
return true
}
または、順序無視バリアント:
infix fun <T> Collection<T>.deepEqualToIgnoreOrder(other: Collection<T>): Boolean {
// check collections aren't same
if (this !== other) {
// fast check of sizes
if (this.size != other.size) return false
val areNotEqual = this.asSequence()
// check other contains next element from this
.map { it in other }
// searching for first negative answer
.contains(false)
if (areNotEqual) return false
}
// collections are same or they are contains same elements
return true
}
注:両方の関数は、ディープの最初のレベルのみを比較します