#android #string #kotlin #coroutine #java.util.concurrent
#Android #строка #котлин #сопрограмма #java.util.concurrent
Вопрос:
Я получаю параллельное исключение, заменяющее строку внутри итератора.
fun replaceValuesInURLString(allFieldsValues: HashMap<String, UserSelectedData>, urlString: String): String {
var result = urlString
val iteratorValues = allFieldsValues.iterator()
while(iteratorValues.hasNext()){
val fieldValue = iteratorValues.next()
val key = "$${fieldValue.key}$"
result = result.replace(key, fieldValue.value.getDataForReg()?: "")
}
//Regex replace to remove query param value's which are not replaced by earlier code
val cleanUpRegex = "(\$)(.*?)(\$)".toRegex()
return cleanUpRegex.replace(result,"")
}
Я получаю параллельное исключение в следующей строке приведенного выше метода.
result = result.replace(key, fieldValue.value.getDataForReg()?: "")
трассировка стека
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1441)
at java.util.HashMap$EntryIterator.next(HashMap.java:1475)
at java.util.HashMap$EntryIterator.next(HashMap.java:1475)
at Validator$DefaultImpls.replaceValuesInURLString(Validator.kt:32)
at replaceValuesInURLString(ProcessedRegField.kt:18)
at Validator$validate$inlined$apply$lambda$1.invokeSuspend(Validator.kt:119)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Комментарии:
1. Что именно находится в строке с номером 32 в
Validator.kt
?2.Вы меняете содержимое этого
allFieldsValues
HashMap
где-то за пределами этой функции?
Ответ №1:
Классы Java Collection быстры в отказоустойчивости, что означает, что если коллекция будет изменена, пока какой-либо поток проходит по ней с помощью итератора, iterator.next() выдаст ConcurrentModificationException , вы можете избежать этого в своей функции.
fun replaceValuesInURLString(allFieldsValues: HashMap<String, UserSelectedData>, urlString: String): String {
var result = urlString
val iteratorValues = allFieldsValues.keySet().iterator()
while(iteratorValues.hasNext()){
val fieldValue = iteratorValues.next()
val key = "$${fieldValue.key}$"
result = result.replace(key, fieldValue.value.getDataForReg()?: "")
}
//Regex replace to remove query param value's which are not replaced by earlier code
val cleanUpRegex = "(\$)(.*?)(\$)".toRegex()
return cleanUpRegex.replace(result,"")
}