Вероятно, есть причина, по которой вы использовали ConsurrentHashMap
вместо обычной Map
реализации, такой как HashMap
.Если вы попытаетесь использовать одну из этих реализаций и запустить свой код, вы заметите ConcurrentModificationException
, которое может быть выброшено всякий раз, когда вы обновляете HashMap
во время итерации по нему.Если вы измените эту реализацию на ConcurrentHashMap
, это изменит следующее:
Хеш-таблица, поддерживающая полный параллелизм получения и высокий ожидаемый параллелизм для обновлений.[...] Операции извлечения (включая get) обычно не блокируются, поэтому могут перекрываться с операциями обновления (включая put и remove).Извлечения отражают результаты самых последних завершенных операций обновления, сохраняющих их начало.
Таким образом, одновременные обновления разрешены, пока вы выполняете итерацию по Map
.Теперь вопрос, можете ли вы на самом деле увидеть значение или нет, может быть связан с порядком итераций реализации Map
(который может меняться в зависимости от версии Java, поскольку в обычно нет порядка итерации в Map
).Если элемент вставлен перед текущей итерацией, он не будет повторен.Если элемент вставлен после, он печатается на консоли.В конце концов, вы не должны на это полагаться.
Однако, если вы снова зациклите Map
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
System.out.println(map.get(it.next()));
}
, вы правильно увидите значение в выводе:
iPhone
HTC one
S5
Xperia Z <<< here it is
iPhone
HTC one
S5
То, что предыдущее предположение верно, теперь можно доказать, поскольку ключ «Sony» был повторен первым, поэтому он не будет отображаться в предыдущей итерации.Если вы сравните это с первой попыткой, клавиша "d" была повторена последней, поэтому она отображается на консоли.Если быть точным, если у вас есть значение, которое повторяется, а не первое значение, оно будет отображаться (поскольку вы добавляете его уже на второй итерации).
Однако, как уже было сказано, имейте в видуэтот порядок итераций может меняться между версиями Java и может применяться только для вашего конкретного примера.