Изменить MutableList во время итерации - PullRequest
0 голосов
/ 07 марта 2020

Хорошо, так. Я абсолютно озадачен этой проблемой. У меня есть функция, которая сортирует список объектов и возвращает его, как 1, 1.1, 1.2, 1.2.1, 2, 2.2, 3.

fun getFolderHierachy(allFolders: List<FolderEntity>): List<FolderEntity>? {

  //puts the entrypoints( 1, 2, 3) in a list
        if (allFolders.isNotEmpty()) {
            val foldersSorted: MutableList<FolderEntity> = mutableListOf()
            allFolders.forEach {
                if (it.parentDir == null) {
                    foldersSorted.add(it)
                }
            }

// should insert an element, after the matching one ( 1, 1.1, 2, 3) 
            while (foldersSorted.size != allFolders.size) {
                foldersSorted.forEach { parentFolder ->
                    allFolders.forEach {
                        if (!foldersSorted.contains(it)) {
                            if (it.parentDir == parentFolder.uid) {
                                val index = foldersSorted.indexOf(parentFolder)
                                foldersSorted.add(index + 1, it)
                            }
                        }
                    }
                }
            }
            println(foldersSorted)
            return foldersSorted
        }
        return null
    }

Я знаю, должно работать, потому что это уже доставил мне правильные результаты. Однако после последнего обновления от моего мастера, он выдает эту ошибку:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: de.ur.mi.audidroid, PID: 16634
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:860)
        at de.ur.mi.audidroid.viewmodels.FolderViewModel.getFolderHierachy(FolderViewModel.kt:206)
        at de.ur.mi.audidroid.viewmodels.FolderViewModel$initFolderSorting$1.onChanged(FolderViewModel.kt:45)
        at de.ur.mi.audidroid.viewmodels.FolderViewModel$initFolderSorting$1.onChanged(FolderViewModel.kt:20)
        at androidx.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Обновление даже не изменило ничего, относящегося к этой функции. Я знаю, что это связано с изменением списка во время итерации, но не должен ли MutableList позаботиться об этом? Я так озадачен тем, как я должен изменить его, чтобы он снова заработал, пожалуйста, помогите.

1 Ответ

1 голос
/ 07 марта 2020

При использовании foreach вы используете List iterator, который не допускает одновременного изменения, пока не существует l oop. Чтобы обойти это, используйте стандартный for l oop.

while (foldersSorted.size != allFolders.size) {
    for (i in 0 until foldersSorted.size) {
        val parentFolder = foldersSorted[i]
        // Rest of code
    }
}
...