Java Academy · Lektion

EnumMap

Effektiva mappar med enumnycklar.

Lektion 4 av 413 steg

EnumMap är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad är EnumMap?

EnumMap är en specialiserad Map vars nycklar är konstanter från en enda enumtyp.

Internt stöds den av en vanlig array som indexeras med konstantens ordinalvärde. Därför är uppslagningar och insättningar extremt snabba utan hashning.

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);
    }
}

Konstruktionen kräver Class

En EnumMap måste känna till nyckeltypen i förväg, så konstruktorn tar Class-objektet: new EnumMap<>(Day.class).

På så sätt kan den dimensionera sin interna array efter antalet konstanter.

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));
    }
}

Arraybaserad snabbhet

Eftersom nycklarna lagras vid array[ordinal] är get och put direkta arrayåtkomster, snabbare än HashMaps hashning och genomgång av buckets.

Nyckeln behöver inte boxas och inget anrop till hashCode görs.

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));
    }
}

Iterering i nyckelordning

EnumMap itererar posterna i nycklarnas naturliga ordning, vilket är deras deklarationsordning.

Det ger stabila och förutsägbara resultat, till skillnad från 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());
        }
    }
}

Nullnycklar är inte tillåtna

EnumMap tillåter inte nullnycklar; en nullnyckel kastar NullPointerException.

Nullvärden är tillåtna, precis som i andra mappar.

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));
    }
}

Gruppering med EnumMap

En vanlig användning är att räkna eller gruppera efter en enumkategori. merge gör det enkelt att räkna samman.

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 och computeIfAbsent

Alla standardmetoder i Map fungerar. getOrDefault eliminerar nullkontroller, och computeIfAbsent bygger värden först när de behövs.

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()));
    }
}

Kopieringskonstruktor

EnumMap har en kopieringskonstruktor som tar emot en annan Map. Om källan är en EnumMap härleds nyckeltypen från den.

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 jämfört med ordinalbaserade arrayer

Före EnumMap använde man råa arrayer indexerade med ordinal(). Det är skört och osäkert.

EnumMap ger samma arrayprestanda med typsäkerhet, gränssäkerhet och ett rent Map-API.

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));
    }
}

Nästlade EnumMaps

Du kan nästla EnumMaps för att modellera en matris som indexeras med två enumtyper, till exempel en tabell över tillståndsövergångar.

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));
    }
}

Välj rätt typ

Tumregel:

  • Nycklarna är enumkonstanter och du vill ha en map: använd EnumMap.
  • Du vill ha en mängd enumtyper: använd EnumSet.
  • Nycklarna är godtyckliga objekt: använd 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);
    }
}

Snabbtest

Testa dina kunskaper om EnumMap.

Sammanfattning

Du har lärt dig om EnumMap:

  • En arraybaserad Map med enumkonstanter som nycklar.
  • Konstruktorn tar nyckelns Class; nullnycklar tillåts inte.
  • Itererar i deklarationsordning.
  • Den säkra och snabba ersättningen för ordinalindexerade arrayer.

Du har slutfört kursen om avancerade enumtyper.

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));
    }
}
Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”EnumMap” gratis?

Ja – hela texten till ”EnumMap” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”EnumMap”?

Effektiva mappar med enumnycklar. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”EnumMap”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Enum med fält och metoder
  2. Abstrakta metoder i enumtyper
  3. EnumSet
  4. EnumMap
← Tillbaka till Java Academy