Java 比较 kotlin 中的两个列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52054104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing two lists in kotlin
提问by Aswin
I came across with kotlin equalsfunction to compare two list of same type. It works fine for pure Kotlin with data classes.
我遇到了 kotlin equals函数来比较两个相同类型的列表。它适用于带有数据类的纯 Kotlin。
I'am using a Java library in Kotlin project in which a callback method returns a list of objects for a time interval of X seconds. Trying to compare the old list with new list for every call, but equals returns false even the items are same and equal.
我在 Kotlin 项目中使用 Java 库,其中回调方法返回 X 秒时间间隔的对象列表。尝试将每次调用的旧列表与新列表进行比较,但即使项目相同且相等,equals 也会返回 false。
val mOldList: MutableList<MyObject>()? = null
override fun updatedList(list: MutableList<MyObject>){
// other code
if (mOldList.equals(list)) // false everytime
}
Is this because of Java's equals method from library?
这是因为库中 Java 的 equals 方法吗?
Alternative suggestions for list compare would be appreciative.
列表比较的替代建议将不胜感激。
回答by Viral Thakker
You can iterate through one list and check the corresponding position value from second list. Take the example below for reference.
您可以遍历一个列表并从第二个列表中检查相应的位置值。以下面的例子供参考。
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
list1.forEachIndexed { i, value ->
if (list2[i] == value)
{
// your implementaion
}
}
Additionally you can filter list for the changed values.
此外,您可以过滤更改值的列表。
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
val changedList = list1.filterIndexed { i, value ->
list2[i] != value)
}
回答by Dakshinamurthy Karra
Java lists implement equals
method and two lists are defined to be equal if they contain the same elements in the same order. I guess, you are missing equals
method in your MyObject
class.
Java 列表实现equals
方法,如果两个列表以相同的顺序包含相同的元素,则它们被定义为相等。我想,你equals
在MyObject
课堂上缺少方法。
回答by amynbe
Using zip
使用zip
zip
returns a list of pairs built from the elements of this array and the other array with the same index. The returned list has length of the shortest collection.
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
}
}
回答by Rene Ferrari
Just fyi you can call list1 == list2
without any extra work, if your custom object is based off of a data class
(which automatically overrides equals for you).
仅供参考list1 == list2
,如果您的自定义对象基于 a data class
(它会自动为您覆盖 equals),则无需任何额外工作即可调用。
回答by Evgenii Vorobei
You could use arrays and contentDeepEquals
:
您可以使用数组和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
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/content-deep-equals.html
回答by XIII-th
You can use implementations below for comparing of two Collection
:
您可以使用下面的实现来比较两个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
}
Or order ignore variant:
或订购忽略变体:
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
}
Note: both function compare only first level of deep
注意:两个函数只比较深度的第一级
回答by DruidKuma
If you don't bother about order of elements in both lists, and your goal is to just check that two lists are of exactly same elements, without any others, you can consider two mutual containsAll
calls like:
如果您不关心两个列表中元素的顺序,并且您的目标只是检查两个列表是否包含完全相同的元素,而没有其他任何元素,则可以考虑两个相互containsAll
调用,例如:
var list1 = mutableListOf<String>()
var list2 = mutableListOf<String>()
if(list1.containsAll(list2) && list2.containsAll(list1)) {
//both lists are of the same elements
}
回答by joecks
:A short version using a extension function:
:使用扩展功能的简短版本:
fun List<*>.deepEquals(other : List<*>) =
this.size == other.size && this.mapIndexed { index, element -> element == other[index] }.all { it }
And you can use it like that:
你可以这样使用它:
listOf("Hola", "Mundo").deepEquals(listOf("Hello", "World"))