Интерфейс Map
Map<K, V> — хранилище пар «ключ → значение», в котором ключи уникальны. Это отдельная ветка коллекций: Map не наследует Collection, но входит в Java Collections Framework и тесно с ним связан.
Основные реализации:
HashMap— хэш-таблица,O(1)в среднем дляget/put. Порядок не определён.LinkedHashMap— сохраняет порядок вставки (или порядок доступа в режиме access-order).TreeMap— отсортированная карта (NavigableMap), операции заO(log n).Hashtable— устаревшая синхронизированная версия; используйтеConcurrentHashMap.
Иерархия
Map<K,V>
├── HashMap<K,V>
│ └── LinkedHashMap<K,V>
├── SortedMap<K,V>
│ └── NavigableMap<K,V>
│ └── TreeMap<K,V>
└── Hashtable<K,V> (legacy)
Основные методы
V put(K key, V value)— добавить/обновитьV get(Object key)— получить значениеV remove(Object key)— удалить записьboolean containsKey(Object key)/containsValue(Object value)Set<K> keySet()/Collection<V> values()/Set<Map.Entry<K,V>> entrySet()V getOrDefault(key, defaultValue)V computeIfAbsent(key, fn)
Пример 1. HashMap — справочник пинов
import java.util.HashMap;
import java.util.Map;
public class MapHashDemo {
public static void main(String[] args) {
Map<String, Integer> pins = new HashMap<>();
pins.put("MOTOR_L_ENB", 6);
pins.put("MOTOR_R_ENA", 5);
pins.put("TRIG", 3);
pins.put("ECHO", 7);
System.out.println("ECHO на пине: " + pins.get("ECHO"));
System.out.println("Есть TRIG? " + pins.containsKey("TRIG"));
System.out.println("Всего: " + pins.size());
}
}
Output:
ECHO на пине: 7
Есть TRIG? true
Всего: 4
Пример 2. Обход через entrySet
import java.util.HashMap;
import java.util.Map;
public class MapIterate {
public static void main(String[] args) {
Map<String, Integer> pins = new HashMap<>();
pins.put("TRIG", 3);
pins.put("ECHO", 7);
pins.put("SERVO", 9);
for (Map.Entry<String, Integer> e : pins.entrySet()) {
System.out.println(e.getKey() + " -> D" + e.getValue());
}
}
}
Output:
SERVO -> D9
ECHO -> D7
TRIG -> D3
Пример 3. TreeMap — отсортированные ключи
import java.util.TreeMap;
public class MapTreeDemo {
public static void main(String[] args) {
TreeMap<Integer, String> sched = new TreeMap<>();
sched.put(2000, "stop");
sched.put(500, "start");
sched.put(1500, "turn");
sched.put(1000, "forward");
for (var e : sched.entrySet()) {
System.out.println(e.getKey() + " ms: " + e.getValue());
}
System.out.println("Первое событие: " + sched.firstKey());
System.out.println("Перед 1200 ms: " + sched.floorEntry(1200));
}
}
Output:
500 ms: start
1000 ms: forward
1500 ms: turn
2000 ms: stop
Первое событие: 500
Перед 1200 ms: 1000=forward
Пример 4. Подсчёт частот через getOrDefault
import java.util.HashMap;
import java.util.Map;
public class MapFrequency {
public static void main(String[] args) {
String[] cmds = {"F", "F", "L", "F", "R", "L", "F"};
Map<String, Integer> freq = new HashMap<>();
for (String c : cmds) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
System.out.println(freq);
}
}
Output:
{R=1, F=4, L=2}
Пример 5. computeIfAbsent для группировки
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MapGroup {
public static void main(String[] args) {
String[] kits = {"Arduino:UNO", "ESP32:WROOM", "Arduino:Mega", "ESP32:CAM"};
Map<String, List<String>> grouped = new HashMap<>();
for (String s : kits) {
String[] p = s.split(":");
grouped.computeIfAbsent(p[0], k -> new ArrayList<>()).add(p[1]);
}
System.out.println(grouped);
}
}
Output:
{ESP32=[WROOM, CAM], Arduino=[UNO, Mega]}
Пример 6. Неизменяемая Map
import java.util.Map;
public class MapImmutable {
public static void main(String[] args) {
Map<String, Integer> pins = Map.of(
"TRIG", 3,
"ECHO", 7,
"SERVO", 9
);
System.out.println("TRIG: " + pins.get("TRIG"));
try {
pins.put("X", 1);
} catch (UnsupportedOperationException e) {
System.out.println("Карта неизменяемая");
}
}
}
Output:
TRIG: 3
Карта неизменяемая
Подводные камни
Ключи
HashMapобязаны корректно реализовыватьhashCode()иequals()— иначеget()вернётnull, даже если ключ «по смыслу» есть.get(key)возвращаетnull, если ключа нет, а также если значение равноnull. Различайте: используйтеcontainsKey().TreeMapтребуетComparableключи илиComparator.null-ключи запрещены.HashMapне потокобезопасен. Для многопоточного кода —ConcurrentHashMap.Map.of(...)не допускаетnullни в ключах, ни в значениях.Изменение ключа после вставки (мутация полей, влияющих на
hashCode) ломает карту.
См. также
Примечание
Материал подготовлен на основе официального руководства Oracle The Collections Framework и распространяется на условиях Oracle Free Documentation License. Тексты переписаны своими словами, примеры кода — оригинальные.