Je suis tombé sur la fonction kotlin equals pour comparer deux listes du même type. Cela fonctionne très bien pour Kotlin pur avec des classes de données.
J'utilise une bibliothèque Java dans le projet Kotlin dans laquelle une méthode de rappel renvoie une liste d'objets pour un intervalle de temps de X secondes. Essayer de comparer l'ancienne liste avec la nouvelle liste pour chaque appel, mais égal renvoie faux même les éléments sont identiques et égaux.
val mOldList: MutableList<MyObject>()? = null
override fun updatedList(list: MutableList<MyObject>){
// other code
if (mOldList.equals(list)) // false everytime
}
Est-ce à cause de la méthode d'égalité de Java de la bibliothèque?
D'autres suggestions de comparaison de liste seraient appréciées.
Les listes Java implémentent la méthode equals
et deux listes sont définies pour être égales si elles contiennent les mêmes éléments dans le même ordre. Je suppose que vous manquez la méthode equals
dans votre classe MyObject
.
Vous pouvez utiliser des tableaux et 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
Utilisation de Zip
Zip
renvoie une liste de paires construites à partir des éléments de ce tableau et de l'autre tableau avec le même index. La liste renvoyée a la longueur de la collection la plus courte.
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
}
}
Juste pour info, vous pouvez appeler list1 == list2
sans aucun travail supplémentaire, si votre objet personnalisé est basé sur un data class
(qui remplace automatiquement égal à vous).
Vous pouvez parcourir une liste et vérifier la valeur de position correspondante dans la deuxième liste. Prenez l'exemple ci-dessous pour référence.
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
list1.forEachIndexed { i, value ->
if (list2[i] == value)
{
// your implementaion
}
}
De plus, vous pouvez filtrer la liste pour les valeurs modifiées.
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
val changedList = list1.filterIndexed { i, value ->
list2[i] != value)
}
Vous pouvez utiliser les implémentations ci-dessous pour comparer deux 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
}
Ou commandez ignorer la variante:
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
}
Remarque: les deux fonctions ne comparent que le premier niveau de profondeur