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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:19:16  来源:igfitidea点击:

Comparing two lists in kotlin

javakotlinkotlin-interop

提问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 equalsmethod and two lists are defined to be equal if they contain the same elements in the same order. I guess, you are missing equalsmethod in your MyObjectclass.

Java 列表实现equals方法,如果两个列表以相同的顺序包含相同的元素,则它们被定义为相等。我想,你equalsMyObject课堂上缺少方法。

回答by amynbe

Using zip

使用zip

zipreturns 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 == list2without 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 containsAllcalls 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"))