순회 순서를 믿어도 되는 경우
이 부분이 언어 간 이식에서 가장 자주 깨집니다. Go는 맵 순회 순서를 의도적으로 무작위화합니다. 순서에 의존하는 코드가 우연히 동작하다가 나중에 터지는 일을 막으려는 설계이므로, 정렬된 출력이 필요하면 키를 따로 모아 정렬해야 합니다. Java의 HashMap은 순서를 명세하지 않으며, 삽입 순서가 필요하면 LinkedHashMap, 키 정렬이 필요하면 TreeMap을 골라야 합니다. Kotlin의 mapOf는 JVM에서 삽입 순서를 유지하는 구현을 씁니다.
Python의 딕셔너리는 삽입 순서 유지가 언어 명세에 포함되어 있고, JavaScript의 Map도 삽입 순서를 보장합니다. 반면 JavaScript 일반 객체는 규칙이 더 복잡해서, 정수처럼 보이는 키가 먼저 오름차순으로 나오고 나머지 문자열 키가 삽입 순서로 뒤따릅니다. ID를 키로 쓰는 객체에서 순서가 뒤집혀 보이는 원인이 대개 이것입니다. PHP 배열은 삽입 순서를 유지하지만, 숫자 문자열 키가 정수로 자동 변환되는 별도의 함정이 있습니다.
정리하면 세 무리로 나뉩니다. 순서를 보장하지 않는다고 명시한 쪽(Go, Java HashMap), 삽입 순서를 보장하는 쪽(Python, JavaScript Map, PHP, Kotlin), 그리고 키 순서로 항상 정렬해 주는 쪽(TreeMap, C++ std::map)입니다. C++은 특히 std::map이 정렬 기반 트리이고 std::unordered_map이 해시 기반이라, 이름만 보고 고르면 성능 특성이 정반대인 자료구조를 쓰게 됩니다.
같은 키란 무엇인가
키 동등성은 자동으로 되는 것이 아닙니다. Java와 Kotlin에서 직접 만든 클래스를 키로 쓰려면 equals와 hashCode를 짝으로 재정의해야 하며, 하나만 고치면 조회가 실패합니다. Kotlin의 data class와 Java의 record는 이 둘을 자동 생성해 주므로 키 타입으로 안전합니다. Python은 키가 해시 가능해야 하고, 그래서 리스트는 키가 될 수 없지만 튜플은 됩니다. JavaScript 일반 객체는 키를 전부 문자열로 강제 변환하므로 숫자 1과 문자열 "1"이 같은 슬롯을 씁니다. Map은 키 타입을 그대로 유지하지만 객체 키는 참조 동일성으로 비교하니, 내용이 같은 두 객체는 서로 다른 키입니다.
동시성에서 특히 주의할 점이 있습니다. Go의 맵은 동시 읽기·쓰기에서 런타임이 프로그램을 강제 종료시킵니다. sync.Mutex로 감싸거나 sync.Map을 써야 합니다. Java의 HashMap도 스레드 안전하지 않아 ConcurrentHashMap이 필요합니다. Python은 GIL 덕분에 단일 연산은 깨지지 않지만, "읽고 판단하고 쓰기"처럼 여러 연산을 묶은 흐름은 여전히 경쟁 상태가 생깁니다.
기본값 처리 관용구도 미리 익혀 두면 코드가 짧아집니다. Python의 dict.get과 collections.defaultdict, Java의 getOrDefault·computeIfAbsent·merge, Kotlin의 getOrElse, Rust의 entry API가 같은 문제를 각자의 방식으로 풉니다. 특히 카운팅이나 그룹핑에서는 이 API를 쓰는 쪽이 조건문을 직접 쓰는 것보다 경쟁 상태와 중복 조회를 함께 줄여 줍니다. 자세한 예제는 심층 가이드의 각 언어 컬렉션 문서에 있습니다.
맵을 언제 쓰지 말아야 하는가
키-값 조회가 필요하다고 해서 항상 해시맵이 정답은 아닙니다. 원소가 열 개 안팎이라면 배열을 선형 탐색하는 쪽이 해시 계산과 포인터 추적을 건너뛰기 때문에 실제로 더 빠른 경우가 흔합니다. 키가 작은 정수 범위에 몰려 있다면 배열 인덱스를 그대로 쓰는 편이 낫고, 키 집합이 컴파일 시점에 고정되어 있다면 열거형이나 구조체 필드로 표현하는 쪽이 오타를 컴파일러가 잡아 줍니다. 설정 값을 문자열 키 맵으로 들고 다니는 코드가 나중에 "이 키가 어디서 쓰이는지 찾을 수 없는" 상태가 되는 것도 같은 맥락입니다.
반대로 맵이 확실히 맞는 자리는 키 집합이 실행 중에 정해지고, 조회가 삽입보다 훨씬 잦으며, 순서가 의미 없는 경우입니다. 자료구조 선택은 이름이 아니라 이 세 조건으로 판단하시는 편이 좋습니다.