如何使用Kotlin就地过滤列表?

BAr*_*ell 23 filtering list kotlin

在Java中,我可以使用以下代码从列表中删除项目:

private void filterList(List<Item> items) {
    Iterator<Item> iterator = items.iterator();
    while (iterator.hasNext()) {
        if (checkItem(iterator.next())) {
            iterator.remove();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在Kotlin中做同样的事情(即删除一些List没有重新创建的项目)?

hot*_*key 45

只需使用.retainAll { ... }.removeAll { ... }接受谓词,就地过滤它:

items.retainAll { shouldRetain(it) }
Run Code Online (Sandbox Code Playgroud)

items.removeAll { shouldRemove(it) }
Run Code Online (Sandbox Code Playgroud)

请注意,items应该是一个MutableList<T>,不仅仅是List<T>,它是Kotlin中的只读列表,因此不会暴露任何变异函数(请参阅:语言参考中的集合).

顺便说一下,对于支持随机访问的列表,这两个函数是有效实现的:然后在删除每个项目之后不压缩列表(O(n 2)时间最坏情况),而是在列表中移动项目它被处理,给出O(n)时间.


如果您不想修改原始列表,则可以生成一个单独的集合,其中只包含您要保留的项目,.filter { ... }或者.filterNot { ... }这也适用于只读List<T>:

val filtered = items.filter { shouldRetain(it) }
Run Code Online (Sandbox Code Playgroud)

val filtered = items.filterNot { shouldRemove(it) }
Run Code Online (Sandbox Code Playgroud)

  • 如果没有这个功能,我会被惊呆了.标准库很棒. (3认同)

Kon*_*hyn 5

Kotlin 有很多简洁的内置函数。您可以尝试使用filter这里。

val filteredItems = items.filter { checkItem(it) }  
Run Code Online (Sandbox Code Playgroud)

不幸的是,它会重新创建列表。此 API 旨在避免额外的可变性。

但是如果你仍然想继续使用 MutableList 使用retainAll方法

items.retainAll { checkItem(it) }
Run Code Online (Sandbox Code Playgroud)