Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Коллекция Map
Определение
Map — это интерфейс в Java Collections Framework, который представляет структуру данных для хранения пар ключ-значение (key-value pairs). Map функционирует как словарь или ассоциативный массив, где каждому уникальному ключу соответствует одно значение.
Основное назначение
1. Хранение и получение данных по ключу
Map предоставляет быстрый доступ к значениям по ключу:
Map<String, Integer> ageMap = new HashMap<>();
// Добавление пары ключ-значение
ageMap.put("Alice", 30);
ageMap.put("Bob", 25);
ageMap.put("Charlie", 35);
// Получение значения по ключу O(1) в среднем
Integer aliceAge = ageMap.get("Alice"); // 30
// Проверка наличия ключа
if (ageMap.containsKey("Bob")) {
System.out.println("Bob найден");
}
2. Основные операции Map
Map<String, String> map = new HashMap<>();
// PUT — добавление/обновление
map.put("key1", "value1");
map.putIfAbsent("key2", "value2"); // Только если ключа нет
// GET — получение значения
String value = map.get("key1"); // "value1"
String def = map.getOrDefault("key3", "default"); // "default"
// REMOVE — удаление
map.remove("key1");
map.remove("key2", "wrongValue"); // Удалит только если значение совпадает
// CHECK — проверка
boolean hasKey = map.containsKey("key1"); // false
boolean hasValue = map.containsValue("value1"); // false
// SIZE — размер
int size = map.size(); // 0
// CLEAR — очистка
map.clear();
3. Основные реализации Map
HashMap — стандартная, неупорядоченная:
Map<Integer, String> map = new HashMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");
for (Integer key : map.keySet()) {
System.out.println(key); // 1, 2, 3 или 3, 1, 2 (не гарантирован порядок)
}
LinkedHashMap — сохраняет порядок вставки:
Map<Integer, String> map = new LinkedHashMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");
for (Integer key : map.keySet()) {
System.out.println(key); // 3, 1, 2 (в порядке вставки)
}
TreeMap — отсортирована по ключам:
Map<Integer, String> map = new TreeMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");
for (Integer key : map.keySet()) {
System.out.println(key); // 1, 2, 3 (в отсортированном порядке)
}
ConcurrentHashMap — потокобезопасная:
Map<String, Integer> map = new ConcurrentHashMap<>();
map.put("count", 0);
// Безопасна для многопоточного доступа
map.computeIfPresent("count", (k, v) -> v + 1);
4. Итерация по Map
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 87);
// Способ 1: По ключам
for (String name : scores.keySet()) {
System.out.println(name + ": " + scores.get(name));
}
// Способ 2: По значениям
for (Integer score : scores.values()) {
System.out.println("Score: " + score);
}
// Способ 3: По парам (рекомендуемый)
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
// Способ 4: Iterator
Iterator<Map.Entry<String, Integer>> it = scores.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next();
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Способ 5: forEach (Java 8+)
scores.forEach((name, score) ->
System.out.println(name + ": " + score)
);
5. Практические примеры использования
Кэширование результатов:
public class Fibonacci {
private Map<Integer, Long> cache = new HashMap<>();
public long fib(int n) {
if (cache.containsKey(n)) {
return cache.get(n); // Быстрое получение из кэша
}
long result = (n <= 1) ? n : fib(n - 1) + fib(n - 2);
cache.put(n, result);
return result;
}
}
Счётчик слов:
public class WordCounter {
public static void main(String[] args) {
String text = "hello world hello java java java";
String[] words = text.split(" ");
Map<String, Integer> wordCount = new HashMap<>();
for (String word : words) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
// Результат: {hello=2, world=1, java=3}
wordCount.forEach((word, count) ->
System.out.println(word + ": " + count)
);
}
}
Конфигурация приложения:
public class Config {
private static final Map<String, String> properties = new HashMap<>();
static {
properties.put("app.name", "MyApplication");
properties.put("app.version", "1.0.0");
properties.put("database.url", "jdbc:mysql://localhost:3306/mydb");
properties.put("database.user", "root");
}
public static String get(String key) {
return properties.get(key);
}
public static String get(String key, String defaultValue) {
return properties.getOrDefault(key, defaultValue);
}
}
// Использование
String appName = Config.get("app.name"); // "MyApplication"
String port = Config.get("app.port", "8080"); // "8080"
Группировка данных:
public class StudentGrouping {
static class Student {
String name;
String department;
Student(String name, String department) {
this.name = name;
this.department = department;
}
}
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("Alice", "CS"),
new Student("Bob", "Math"),
new Student("Charlie", "CS"),
new Student("Diana", "Math")
);
// Группировка по отделению
Map<String, List<String>> byDepartment = new HashMap<>();
for (Student student : students) {
byDepartment.computeIfAbsent(student.department, k -> new ArrayList<>())
.add(student.name);
}
// {CS=[Alice, Charlie], Math=[Bob, Diana]}
byDepartment.forEach((dept, names) ->
System.out.println(dept + ": " + names)
);
}
}
6. Производительность основных операций
| Операция | HashMap | LinkedHashMap | TreeMap | ConcurrentHashMap |
|---|---|---|---|---|
| get() | O(1) | O(1) | O(log n) | O(1) |
| put() | O(1) | O(1) | O(log n) | O(1) |
| remove() | O(1) | O(1) | O(log n) | O(1) |
| Порядок | Нет | Вставки | Сортирован | Нет |
| Потокобезопасность | Нет | Нет | Нет | Да |
7. computeIfPresent и computeIfAbsent
Map<String, Integer> map = new HashMap<>();
// computeIfAbsent — вычислить если ключа нет
map.computeIfAbsent("a", k -> 1); // map.put("a", 1)
// computeIfPresent — вычислить если ключ есть
map.computeIfPresent("a", (k, v) -> v + 1); // map.put("a", 2)
// compute — вычислить в любом случае
map.compute("a", (k, v) -> v == null ? 1 : v + 1);
// merge — слияние значений
map.merge("a", 10, Integer::sum); // a = 2 + 10 = 12
Выводы
Map — фундаментальная коллекция Java для:
- Быстрого поиска значений по ключу (O(1) для HashMap)
- Хранения пар ключ-значение
- Кэширования и индексирования данных
- Подсчёта частот элементов
- Группировки и классификации данных
- Конфигурации приложений
Выбор реализации (HashMap, LinkedHashMap, TreeMap) зависит от требований к порядку, производительности и потокобезопасности.