java.util.concurrentmodificationexception即使使用迭代器也从arraylist中删除元素时

368yc8dk  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(331)

我正在尝试在满足特定条件时从两个ArrayList中删除内容。但当条件满足时,得到并发修改错误。在互联网上搜索之后,我看到了使用迭代器概念来解决这个问题的解决方案,但这也不起作用。
下面是我尝试的两个代码变体:[我的代码在kotlin中]
第一个变化:删除后立即得到错误

var index = 0
        for (snap: DataSnapshot in snaps){
            if (snap.key == snapshot.key){
                snaps.removeAt(index)
                emailOfSenders.removeAt(index)
            }

            index++
        }

第二种变体:如果arraylist中的项少于3,则有效,但如果项是3或多于3,则会得到相同的错误

var index = 0

        val iter: Iterator<DataSnapshot> = snaps.iterator()
        while (iter.hasNext()) {
            val snap: DataSnapshot = iter.next()
            if (snap.key == snapshot.key){
                snaps.removeAt(index)
                emailOfSenders.removeAt(index)
            }

            index++
        }

错误日志:

2020-11-18 13:52:32.829 18935-18935/com.rofy.snapyandroid E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.rofy.snapyandroid, PID: 18935
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:860)
        at com.rofy.snapyandroid.SnapsActivity$onCreate$1.onChildRemoved(SnapsActivity.kt:54)
        at com.google.firebase.database.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:88)
        at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

更多信息:我正在创建一个snapchat克隆应用程序,我正在使用谷歌的firebase为它一切工作完美,即上传,下载,删除在firebase。所以我不认为这是火基问题

nnsrf1az

nnsrf1az1#

如果你在一个 collection 使用 iterator 那么您只能修改 collection 使用迭代器的mutator方法,如果您尝试使用集合的mutator方法(remove、set等)修改集合,那么 iterator 投掷 ConcurrentModificationException ,这就是迭代器的fail fast特性。
在您的情况下,不应该执行snap.removeat(index),而应该执行iterator.remove()
请注意,iterator.remove删除迭代器返回的最后一个元素。因此,要删除元素,必须首先调用next()方法。
例如,假设要删除第一个元素。要做到这一点,你必须做到以下几点。

iterator.next()
iterator.remove() // Removes the element returned by next

如果arraylist中的项小于3,则有效,但如果项为3或大于3,则会出现相同的错误
这是因为 ConcurrentModificationException 是由 next() 方法,因为在有1或2个元素的情况下,它只被调用一次,所以在任何修改之前都要调用,所以不会出现任何错误。在上述情况下,执行以下步骤:

1. iterator.hasNext()      // returns true 
2. iterator.next()         // works fine, since we have not modified collection yet
3. snaps.removeAt(index)   // removes one element
4. iterator.hasNext()      // returns false as there is only one element in list
5. iterator.next           // this line is not executed and hence no error

相关问题