我有一个帐户列表,当我进行长按时,我想从arraylist中删除该项目。我正在尝试从alertdialog中删除它,但我得到了ConcurrentModificationException。这就是崩溃的地方:
listAccounts.forEachIndexed { index, account ->
if (idParamether == account.id) {
listAccounts.remove(account)
}
}
答案 0 :(得分:8)
在Kotlin中,您可以使用removeIf{ predicate }
。这是使用Iterator
的简写。完整声明:
listAccounts.removeIf{ it == account.id }
有关说明,请参阅Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop
答案 1 :(得分:2)
val iterator = updatedList?.iterator()
iterator?.forEach {
if(it.id == someObj.id) {
oldSubscription = it
iterator.remove()
}
}
与SeekDaSky相同的解决方案,但更多Kotlin'y
答案 2 :(得分:2)
kotlin stdlib实际上是removeAll { predicate }
引入的。
因此您的代码应如下所示:
listAccounts.removeAll { it.id == idParamether }
请参阅:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/remove-all.html
注意:当使用Kotlin进行编码时,我更喜欢使用Kotlin API,这样可以避免出现“调用需要API级别24”之类的问题
答案 3 :(得分:1)
这是JVM的一个常见问题,如果你想在迭代它时从一个集合中删除一个项目,你需要使用Iterators
为例:
val myCollection = mutableListOf(1,2,3,4)
val iterator = myCollection.iterator()
while(iterator.hasNext()){
val item = iterator.next()
if(item == 3){
iterator.remove()
}
}
这将避免ConcurrentModificationExceptions
我希望这能回答你的问题,祝你有个美好的一天
编辑:您可以找到另一个解释here,即使它是Java代码,问题也是相同的 编辑n°2 leonardkraemer的anwser向您展示了更加友好的kotlin方式
答案 4 :(得分:1)
请尝试使用ConcurrentLinkedQueue而不是list来避免此异常。
正如ConcurrentLinkedQueue.Java中提到的那样,它对元素FIFO(先进先出)进行排序。因此,它将避免在迭代列表时修改列表的任何问题。
例如:
val list = ConcurrentLinkedQueue<String>()
list.add("toto")
list.add("tata")
list.add("titi")
list.forEachIndexed { index, it ->
if (index % 2 == 0) {
list.remove("tata")
System.out.println(it)
}
}
输出是:
托托
蒂蒂
答案 5 :(得分:1)
我想补充Ryan's answer。如果您想在迭代期间添加到列表中,而不仅仅是删除,则需要在集合上调用.listIterator()
而不是.iterator()
。然后,借助this interface,您还将拥有add
方法。
完整的代码:
with(listAccounts.listIterator()) {
forEach {
if (it.id == someObj.id) {
// do some stuff with it
oldSubscription = it
remove()
add(obj)
}
}
}
注意:我知道OP只是想删除,但是标题更为笼统,如果在这种情况下也搜索添加,这也是您所遇到的问题。
答案 6 :(得分:0)
您可以在遍历列表之前制作一个副本。这是小列表的有效解决方案。例如,这就是他们在遍历侦听器之前通常在 Android 上执行的操作。
答案 7 :(得分:0)
解决这个问题最简单的方法就是在删除后添加“break”
for (i in accounts) {
if (nick == i.nick) {
print("Enter PIN: ")
var pin = scan.nextInt()
if (pin == i.pin) {
accounts.remove(i)
println("Account has been deleted successfully!")
break
}
}
}
答案 8 :(得分:0)
我也遇到了这个问题,我只是通过克隆起始列表来解决它,所以我经历了这个过程并添加或删除了原始列表中的元素。
这段代码给了我一个例外:
for(account in listAccounts){
....
myCollection.add(anotherAccount)
....
}
所以只需将其替换为:
val listAccountCloned = listAccounts.toMutableList()
for(account in listAccountCloned){
....
myCollection.add(anotherAccount)
....
}