Как перебрать Map
Короткий ответ
entrySet() возвращает пары «ключ — значение»:
void main() {
Map<String, Integer> stock = new LinkedHashMap<>();
stock.put("apples", 10);
stock.put("pears", 4);
for (Map.Entry<String, Integer> entry : stock.entrySet()) {
IO.println(entry.getKey() + " = " + entry.getValue());
}
}Результат:
apples = 10
pears = 4Метод forEach
Лямбда в forEach() сразу получает ключ и значение:
void main() {
var stock = new TreeMap<>(Map.of("pears", 4, "apples", 10));
stock.forEach((fruit, count) -> IO.println(fruit + ": " + count));
}Результат:
apples: 10
pears: 4Только ключи или значения
keySet() возвращает ключи, values() — значения:
void main() {
var prices = new TreeMap<>(Map.of("tea", 3, "cake", 12));
IO.println(prices.keySet());
IO.println(prices.values().stream().mapToInt(Integer::intValue).sum());
}Результат:
[cake, tea]
15Порядок обхода
HashMap не гарантирует порядок. LinkedHashMap хранит порядок добавления, TreeMap сортирует ключи.
Частая ошибка
Удалять элементы из Map внутри цикла for-each. Это вызывает ConcurrentModificationException:
void main() {
var stock = new HashMap<>(Map.of("apples", 0, "pears", 4, "plums", 0));
for (String key : stock.keySet()) {
if (stock.get(key) == 0) {
stock.remove(key);
}
}
}Результат:
Exception in thread "main" java.util.ConcurrentModificationExceptionИспользуйте removeIf(): stock.values().removeIf(count -> count == 0).
Функции из этого ответа
- Map.entrySet() — Возвращает все пары «ключ — значение» для обхода.
- Map.forEach() — Выполняет действие для каждой пары словаря.
- Map.keySet() — Возвращает множество всех ключей словаря.
- Map.values() — Возвращает коллекцию всех значений словаря.