Атомарное обновление Map с помощью compute и merge
Замените многоэтапный поиск и изменение Map методами computeIfAbsent(), compute() и merge().
Сравнение кода
✕ Manual lookup and update
List<String> values = groups.get(key);
if (values == null) {
values = new ArrayList<>();
groups.put(key, values);
}
values.add(value);
✓ Java 8+
groups.computeIfAbsent(key, ignored -> new ArrayList<>())
.add(value);
Заметили проблему в этом коде? Сообщите нам.
Почему современный подход лучше
Меньше поисков
Исключает повторный доступ по ключу.
Улучшенная семантика конкурентности
Конкурентные отображения могут атомарно выполнять поддерживаемые обновления.
Ясное намерение
Правило инициализации находится рядом с обращением к значению.
Старый подход
get() + проверка на null + put()
Современный подход
computeIfAbsent()
Начиная с JDK
8
Сложность
Средний
Поддержка JDK
Атомарное обновление Map с помощью compute и merge
Доступно
Широко доступно начиная с JDK 8 (март 2014)
Как это работает
Вычисляющие методы Map объединяют поиск и обновление в одной операции. Используйте computeIfAbsent() для ленивой инициализации, compute(), когда новое значение зависит от существующего, и merge(), чтобы объединить переданное значение с уже находящимся в Map. В реализациях конкурентных отображений поддерживаемые вычисления также предотвращают гонки, возникающие из-за отдельных вызовов get() и put().
Связанная документация
Доказательство