ConcurrentModificationException в HashMap

Я беру детали страхования от пользователя и сохраняю их в хэш-карте. И у меня есть кнопка под названием SAVE. Таким образом, только когда пользователь нажимает на эту кнопку, все страховки должны сохраняться в базе данных. Поэтому я беру случайный сгенерированный идентификатор в качестве ссылки, пока не сохраню детали в базе данных. После сохранения в базе данных мне нужно обновить эту хэш-карту с ключом в качестве автоматически сгенерированного идентификатора.

public void saveInformationInDatabase(int patientId)
{
    // getAllInsurances returns HashMapn<Integer, HashMap<Integer, InsuranceInformation>>
    Iterator<Map.Entry<Integer, InsuranceInformation>> insurances = getAllInsurances().get(patientId).entrySet().iterator();
    while(insurances.hasNext())
    {
        InsuranceInformation insuranceInformation = insurances.next().getValue();
        if (insuranceInformation.getStatus() == Status.OLD)
            continue;
        else if (insuranceInformation.getStatus() == Status.NEW)
        {
            // Saving the Information in database, and returning auto generated ID
            int licId = saveInformation(insuranceInformation);
            // So, i need to update insuranceInformation with autogenerated ID
            // Because previous id is randomly generated number
            insuranceInformation.setLicID(licId);
            insuranceInformation.setStatus(InsuranceObject.Status.OLD);
            // Below line gives me ConcurrentModificationException
            getAllInsurances().get(patientId).put(licId, insuranceInformation); // Storing the updated information with newly generated id as key, in hashmap
            insurances.remove(); // and here, removing the old hashmap entry
        }
    }
}

1 ответ

Решение

getAllInsurances().get(patientId).put(licId, insuranceInformation); обновляет Map когда вы пытаетесь выполнить итерацию, это вызывает исключение, так как вы не можете изменить коллекцию, пока вы выполняете ее.

Вместо этого вы должны использовать второй Map хранить обновленные значения и использование Map#putAll например, чтобы синхронизировать их два...

// Test map full of values...
Map<Integer, String> mapTest = new HashMap<>(25);
for (int index = 0; index < 10; index++) {
    mapTest.put(index, Integer.toString(index));
}

// Grab an iterator
Iterator<Map.Entry<Integer, String>> insurances = mapTest.entrySet().iterator();
// Create a temp map for the new values
Map<Integer, String> newValues = new HashMap<>(25);
while(insurances.hasNext()) {

    Map.Entry<Integer, String> entry = insurances.next();
    int key = entry.getKey();
    // Make the comparison about what we want to do, here
    // we're removing even keys
    if (key % 2 == 0) {
        // Remove the old entry
        insurances.remove();
        // Use the temp map to create a new entry
        newValues.put(key * 10, entry.getValue());
    }

}

// Merge the results
mapTest.putAll(newValues);

Как одно из возможных решений

Другие вопросы по тегам