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

时间:2017-06-21 11:14:02

标签: list kotlin filtering

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

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

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

3 个答案:

答案 0 :(得分:38)

只需使用接受谓词的.retainAll { ... }.removeAll { ... }即可对其进行过滤:

items.retainAll { shouldRetain(it) }

items.removeAll { shouldRemove(it) }

请注意,items应该是MutableList<T>,而不仅仅是List<T>,它是Kotlin中的只读列表,因此不会公开任何变异函数(请参阅:{语言参考中的{3}}。

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

如果您不想修改原始列表,则可以使用Collections.filter { ... }生成仅包含要保留的项目的单独集合,这将仅用于只读List<T>也是:

val filtered = items.filter { shouldRetain(it) }

val filtered = items.filterNot { shouldRemove(it) }

答案 1 :(得分:4)

Kotlin有很多简洁的内置功能。您可以尝试在此使用filter

val filteredItems = items.filter { checkItem(it) }  

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

但是如果您仍想继续使用MutableList,请使用retainAll方法

items.retainAll { checkItem(it) }

答案 2 :(得分:0)

这将从列表1-9中删除偶数,并打印[1, 3, 5, 7, 9]

var myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
myLists.removeAll{ it % 2 == 0 }
println(myLists)

这将保留偶数并将其他数字从列表1-9中删除,并打印[2, 4, 6, 8]

myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
myLists.retainAll{ it % 2 == 0 }
println(myLists)

https://play.kotlinlang.org/中试用它们