0Pricing
Java Academy · 강의

EnumMap

열거형을 키로 사용하는 효율적인 맵입니다

EnumMap은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

EnumMap이란 무엇인가요

EnumMap은 하나의 열거형 형식에 속한 상수를 키로 사용하는 특수한 Map입니다.

내부적으로는 상수의 ordinal을 인덱스로 사용하는 일반 배열을 기반으로 합니다. 따라서 해싱 없이 조회와 삽입을 매우 빠르게 수행할 수 있습니다.

import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum Day { MON, TUE, WED }
    public static void main(String[] args) {
        Map<Day, String> plan = new EnumMap<>(Day.class);
        plan.put(Day.MON, "Gym");
        plan.put(Day.WED, "Swim");
        System.out.println(plan);
    }
}

생성하려면 클래스를 지정해야 합니다

EnumMap은 키 형식을 미리 알아야 하므로 생성자에 클래스 객체를 전달합니다: new EnumMap<>(Day.class).

이를 통해 내부 배열의 크기를 상수 개수에 맞게 설정합니다.

import java.util.EnumMap;

public class Main {
    enum Priority { LOW, MEDIUM, HIGH }
    public static void main(String[] args) {
        EnumMap<Priority, Integer> counts = new EnumMap<>(Priority.class);
        counts.put(Priority.HIGH, 5);
        System.out.println(counts.get(Priority.HIGH));
    }
}

배열 기반 성능

키가 array[ordinal] 위치에 저장되므로 get과 put은 직접 배열에 접근합니다. HashMap의 해싱과 버킷 순회보다 빠릅니다.

키를 박싱하지 않으며 hashCode 호출도 발생하지 않습니다.

import java.util.EnumMap;

public class Main {
    enum Slot { A, B, C, D }
    public static void main(String[] args) {
        EnumMap<Slot, Integer> m = new EnumMap<>(Slot.class);
        for (Slot s : Slot.values()) m.put(s, s.ordinal() * 10);
        System.out.println(m.get(Slot.C));
    }
}

키 순서로 순회하기

EnumMap은 키의 자연 순서, 즉 키의 선언 순서로 항목을 순회합니다.

따라서 HashMap과 달리 안정적이고 예측 가능한 출력이 제공됩니다.

import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum Phase { PLAN, BUILD, SHIP }
    public static void main(String[] args) {
        Map<Phase, Integer> hours = new EnumMap<>(Phase.class);
        hours.put(Phase.SHIP, 3);
        hours.put(Phase.PLAN, 8);
        hours.put(Phase.BUILD, 20);
        for (Map.Entry<Phase, Integer> e : hours.entrySet()) {
            System.out.println(e.getKey() + " = " + e.getValue());
        }
    }
}

널 키는 금지됩니다

EnumMap은 널 키를 허용하지 않으며, 널 키를 사용하면 NullPointerException이 발생합니다.

널 값은 다른 Map과 마찬가지로 허용됩니다.

import java.util.EnumMap;

public class Main {
    enum K { A, B }
    public static void main(String[] args) {
        EnumMap<K, String> m = new EnumMap<>(K.class);
        m.put(K.A, null); // null value is fine
        System.out.println("A -> " + m.get(K.A));
        System.out.println("contains A: " + m.containsKey(K.A));
    }
}

EnumMap으로 그룹화하기

열거형 범주별로 개수를 세거나 그룹화하는 것이 일반적인 사용 방법입니다. merge를 사용하면 집계를 간결하게 작성할 수 있습니다.

import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class Main {
    enum Type { FRUIT, VEG, MEAT }
    record Item(String name, Type type) {}
    public static void main(String[] args) {
        List<Item> items = List.of(new Item("apple", Type.FRUIT), new Item("pear", Type.FRUIT), new Item("beef", Type.MEAT));
        Map<Type, Integer> counts = new EnumMap<>(Type.class);
        for (Item i : items) counts.merge(i.type(), 1, Integer::sum);
        System.out.println(counts);
    }
}

getOrDefault 및 computeIfAbsent

모든 표준 Map 기본 메서드가 작동합니다. getOrDefault는 널 검사를 피하고, computeIfAbsent는 값을 지연하여 생성합니다.

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class Main {
    enum Group { A, B }
    public static void main(String[] args) {
        Map<Group, List<String>> m = new EnumMap<>(Group.class);
        m.computeIfAbsent(Group.A, k -> new ArrayList<>()).add("first");
        System.out.println(m);
        System.out.println(m.getOrDefault(Group.B, List.of()));
    }
}

복사 생성자

EnumMap에는 다른 Map을 받는 복사 생성자가 있습니다. 원본이 EnumMap이면 키 형식이 원본에서 추론됩니다.

import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum K { X, Y }
    public static void main(String[] args) {
        EnumMap<K, Integer> a = new EnumMap<>(K.class);
        a.put(K.X, 1);
        EnumMap<K, Integer> b = new EnumMap<>(a);
        b.put(K.Y, 2);
        System.out.println("copy: " + b);
    }
}

EnumMap과 ordinal 배열 비교

EnumMap이 없던 시절에는 ordinal()을 인덱스로 사용하는 일반 배열을 사용했습니다. 이 방식은 취약하고 안전하지 않습니다.

EnumMap은 형식 안전성, 범위 안전성, 깔끔한 Map 인터페이스를 갖추면서도 동일한 배열 성능을 제공합니다.

import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum Season { SPRING, SUMMER, FALL, WINTER }
    public static void main(String[] args) {
        Map<Season, String> mood = new EnumMap<>(Season.class);
        mood.put(Season.SUMMER, "sunny");
        // Safer and clearer than String[] indexed by ordinal
        System.out.println(mood.get(Season.SUMMER));
    }
}

중첩 EnumMap

두 열거형을 키로 사용하는 행렬을 모델링하기 위해 EnumMap을 중첩할 수 있습니다. 예를 들어 상태 전이 표를 만들 때 사용할 수 있습니다.

import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum State { SOLID, LIQUID, GAS }
    enum Transition { MELT, FREEZE }
    public static void main(String[] args) {
        Map<State, Map<Transition, State>> table = new EnumMap<>(State.class);
        Map<Transition, State> solid = new EnumMap<>(Transition.class);
        solid.put(Transition.MELT, State.LIQUID);
        table.put(State.SOLID, solid);
        System.out.println(table.get(State.SOLID).get(Transition.MELT));
    }
}

적절한 형식 선택하기

기본 규칙은 다음과 같습니다.

  • 키가 열거형 상수이고 Map이 필요하면 EnumMap을 사용합니다.
  • 열거형 집합이 필요하면 EnumSet을 사용합니다.
  • 키가 임의의 객체라면 HashMap을 사용합니다.
import java.util.EnumMap;
import java.util.Map;

public class Main {
    enum Level { DEBUG, INFO, WARN, ERROR }
    public static void main(String[] args) {
        Map<Level, Integer> thresholds = new EnumMap<>(Level.class);
        for (Level l : Level.values()) thresholds.put(l, l.ordinal() * 100);
        System.out.println(thresholds);
    }
}

빠른 확인

EnumMap에 대한 지식을 확인해 보세요.

복습

EnumMap을 배웠습니다.

  • 열거형 상수를 키로 사용하는 배열 기반 Map입니다.
  • 생성자는 키 클래스를 받으며, 널 키는 허용되지 않습니다.
  • 선언 순서로 순회합니다.
  • ordinal을 인덱스로 사용하는 배열을 안전하고 빠르게 대체합니다.

고급 열거형 과정을 모두 마쳤습니다.

import java.util.EnumMap;

public class Main {
    enum K { A }
    public static void main(String[] args) {
        EnumMap<K, String> m = new EnumMap<>(K.class);
        m.put(K.A, "done");
        System.out.println("EnumMap course complete: " + m.get(K.A));
    }
}

자주 묻는 질문

“EnumMap” 강의는 무료인가요?

네 — “EnumMap” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“EnumMap”에서 뭘 배우나요?

열거형을 키로 사용하는 효율적인 맵입니다 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“EnumMap” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 필드와 메서드가 있는 열거형
  2. 열거형의 추상 메서드
  3. EnumSet
  4. EnumMap
← Java Academy(으)로 돌아가기