问题描述
我目前正在学习来自Java的Kotlin。在Java中,
for(String s:stringList){
if(condition == true) stringList.remove(s);
}
无效,因为您只能读取各自的数据。这是否也适用于Kotlin?
解决方法
与Java中的限制相同-遍历集合时,您只能通过Iterator
的{{3}}方法对其进行修改
从基础集合中移除此迭代器返回的最后一个元素(可选操作)。每次调用next()只能调用一次此方法。 如果在迭代进行过程中以其他方式(而不是通过调用此方法)修改基础集合,则未指定迭代器的行为。
Kotlin具有remove()
(请记住,Kotlin使用了可变列表和不可变列表的概念,因此只能使用MutableList
来做到这一点)
foreach
/增强型for
结构的问题在于它不会暴露您需要调用Iterator
的{{1}},并且您不能在集合本身上调用remove()
。和Kotlin一样-所以您的选择基本上是
- 使用
remove()
/for
(但您不能修改集合) - 调用集合的
forEach
方法并自己对其进行迭代(现在,您可以在我引用的限制下对其调用iterator()
) - 避免变异并产生新的收藏
最后一个是鼓励您在Kotlin中进行的操作-与其修改集合,不如尝试使用不可变的集合并将其转换为新的集合:
remove()
如果您熟悉所有的its own equivalent(是的,有很多 ),您将会了解将A转换为B的方法,方便的功能可以帮助您完成此操作(例如collection functions,可让您提供stringList.filterNot { condition }
来填充要保留的项目)。
但是,如果您确实想修改可变集合,则有可能,但您必须自己进行管理,因为这具有固有的危险性,并且系统无法保证您安全地进行操作。
,是的,如果您使用Kotlin重写此代码,则会遇到相同的并发修改问题:
for (s in stringList) {
if(condition == true) stringList.remove(s)
}
为避免此问题,您可以从可变列表中获取可变迭代器,并使用它来随时删除元素。但是与Java不同,您不必通过hasNext()
/ next()
调用手动对其进行迭代-您可以使用相同的for
运算符对其进行迭代:
val iterator = stringList.iterator()
for (s in iterator) {
if (condition == true) iterator.remove()
}