java removeall和removeif的使用情形

nfeuvbwi  于 2023-02-11  发布在  Java
关注(0)|答案(4)|浏览(321)

我发现了这个:

fun main() {
    val list: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5)

    list.removeAll { x -> x in 1..3 } // [4, 5]
    list.removeIf { x -> x in 1..3 } // [4, 5]
}

两者都产生相同的结果。
虽然我知道removeAll是Kotlin,removeIf是Java,但我不明白为什么removeIf已经在那里了,removeAll还在那里?
事实上,我们可以在Kotlin中使用removeIf而不会有任何麻烦,或者是否有任何用例可能需要一个又一个?

6gpjuf90

6gpjuf901#

还有一个重要的区别:
CopyOnWriteArrayList上调用removeIf线程安全的,但是removeAll不是
看一下代码,removeIf有一个CopyOnWriteArrayList的自定义实现,但是removeAll迭代索引,最终将抛出ArrayIndexOutOfBoundsException,甚至更糟,如果并发调用,将删 debugging 误的元素

sg2wtvxw

sg2wtvxw2#

Java的removeIf()从Java 1.8开始就存在了。
Kotlin从2011年开始(wikipedia),Java 1.8出现在2014年。
我不确定Kotlin的removeAll(predicate)是什么时候被指定和实现的,但是它可能早于Java的removeIf()

7gcisfzg

7gcisfzg3#

这是两个非常不同的函数,但是在Kotlin中这个方法被重载了,这意味着,它有两种不同类型的参数。
如果你读了文档,你会发现你可以通过给一个集合来使用这个函数:

fun <T> MutableCollection<out T>.removeAll(
    elements: Collection<T>
): Boolean (source)

或者给一个函数来过滤:

fun <T> MutableIterable<T>.removeAll(
    predicate: (T) -> Boolean
): Boolean (source)

所以,第二个类似于Java版本的removeIf,第一个不是。

nxagd54h

nxagd54h4#

两者都产生相同的结果。
结果是以完全不同的方式实现的,所以它可能不总是完全相同的。
removeAll是一个方便的方法,它是一个多次调用removeAt的简单循环。
removeIf是一个原生的ArrayList方法,它直接操作内部elementData,绕过所有旧的删除方法和任何可能放在那里的逻辑。这里的坏消息是,它被追溯性地覆盖应用到从ArrayList派生的所有内容,而忽略旧的实现。
或者,是否有任何用例可能需要一个而不是另一个?
一个例子是androidx.databinding.ObservableList,它早于removeIf,并且不发送到期删除通知,因此要么默默地破坏代码,要么导致cryptic errors

相关问题