如何使用 Kotlin 就地过滤列表?
Posted
技术标签:
【中文标题】如何使用 Kotlin 就地过滤列表?【英文标题】:How to filter a list in-place with Kotlin? 【发布时间】:2017-11-24 06:22:01 【问题描述】:在 Java 中,我可以使用以下代码从列表中删除项目:
private void filterList(List<Item> items)
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext())
if (checkItem(iterator.next()))
iterator.remove();
如何在 Kotlin 中做同样的事情(即删除 List
中的一些项目而不重新创建)?
【问题讨论】:
只需将此代码复制到kotlin文件,IDE会自动为您完成。 【参考方案1】:只需使用都接受谓词的.retainAll ...
或.removeAll ...
就地过滤它:
items.retainAll shouldRetain(it)
items.removeAll shouldRemove(it)
请注意,items
应该是 MutableList<T>
,而不仅仅是 List<T>
,它是 Kotlin 中的只读列表,因此不会公开任何变异函数(请参阅语言参考中的 Collections )。
顺便说一句,对于支持随机访问的列表,这两个函数是有效实现的:那么在删除每个项目后列表不会被压缩(O(n2) 时间最坏情况),而是在处理列表时在列表中移动项目,给了 O(n) 时间。
如果您不想修改原始列表,您可以使用.filter ...
或.filterNot ...
生成一个单独的集合,其中仅包含您想要保留的项目,这将适用于只读List<T>
为好吧:
val filtered = items.filter shouldRetain(it)
val filtered = items.filterNot shouldRemove(it)
【讨论】:
如果没有这个功能,我会惊呆的。标准库很棒。 您的意思是removeAll
?因为在问题中,当谓词通过时删除了一个项目。
@Ilya,谢谢,这只是checkItem
的名字让我很困惑。固定。【参考方案2】:
Kotlin 有很多简洁的内置函数。你可以在这里尝试使用filter
。
val filteredItems = items.filter checkItem(it)
不幸的是,它将重新创建列表。此 API 旨在避免额外的可变性。
但如果您仍想继续使用 MutableList,请使用 retainAll
方法
items.retainAll checkItem(it)
【讨论】:
【参考方案3】:这将从列表 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/试试他们
【讨论】:
以上是关于如何使用 Kotlin 就地过滤列表?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Rxjava 在 Android Kotlin 中过滤数据
如何将二叉树就地转换为二叉搜索树,即我们不能使用任何额外的空间