如何使用 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&lt;T&gt;,而不仅仅是 List&lt;T&gt;,它是 Kotlin 中的只读列表,因此不会公开任何变异函数(请参阅语言参考中的 Collections )。

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


如果您不想修改原始列表,您可以使用.filter ... .filterNot ... 生成一个单独的集合,其中仅包含您想要保留的项目,这将适用于只读List&lt;T&gt; 为好吧:

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 就地过滤列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CListCtrl 就地编辑列?

验证列表控件就地编辑

如何使用 Rxjava 在 Android Kotlin 中过滤数据

如何将二叉树就地转换为二叉搜索树,即我们不能使用任何额外的空间

如何使用 Kotlin 在 ListAdapter 中使用 Filterable?

Kotlin - 列表过滤中的列表