Java Academy · Oppitunti

EnumMap

Tehokkaat enum-avaimiset kartat.

Oppitunti 4/413 vaihetta

EnumMap on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mikä EnumMap on?

EnumMap on erityinen Map, jonka avaimet ovat yhden enum-tyypin vakioita.

Sisäisesti se perustuu tavalliseen taulukkoon, jonka indeksinä on vakion ordinal-arvo. Siksi haut ja lisäykset ovat erittäin nopeita, eikä hajautusta tarvita.

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

Luominen edellyttää Class-oliota

EnumMapin on tunnettava avaintyyppi etukäteen, joten konstruktori ottaa vastaan Class-olion: new EnumMap<>(Day.class).

Näin se voi mitoittaa sisäisen taulukkonsa vakioiden määrän mukaan.

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

Taulukkopohjainen nopeus

Koska avaimet tallennetaan kohtiin array[ordinal], get- ja put-operaatiot ovat suoria taulukkomuistihakuja ja nopeampia kuin HashMapin hajautus ja lokeroiden läpikäynti.

Avainta ei paketoida, eikä metodia hashCode kutsuta.

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

Iterointi avainten järjestyksessä

EnumMap iteroi alkiot avainten luontaisessa järjestyksessä, joka on niiden määrittelyjärjestys.

Tämä tuottaa vakaan ja ennakoitavan tulosteen toisin kuin 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());
        }
    }
}

Null-avaimet eivät ole sallittuja

EnumMap ei salli null-avaimia; null-avain aiheuttaa poikkeuksen NullPointerException.

Null-arvot ovat sallittuja kuten muissakin kartoissa.

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

Ryhmittely EnumMapilla

Yleinen käyttötapaus on laskeminen tai ryhmittely enum-luokan mukaan. merge tekee lukumäärien laskemisesta tiivistä.

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

Kaikki Map-rajapinnan vakiometodit toimivat. getOrDefault välttää null-tarkistukset, ja computeIfAbsent luo arvot tarvittaessa.

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

Kopiokonstruktori

EnumMapilla on kopiokonstruktori, joka hyväksyy toisen Mapin. Jos lähde on EnumMap, avaintyyppi päätellään siitä.

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 ja ordinal-taulukot

Ennen EnumMapia käytettiin suoraan ordinal()-arvon perusteella indeksoituja taulukoita. Tämä on hauras ja turvaton ratkaisu.

EnumMap tarjoaa saman taulukon nopeuden sekä tyyppiturvallisuuden, indeksirajojen tarkistuksen ja selkeän Map-rajapinnan.

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

Sisäkkäiset EnumMapit

Voitte sijoittaa EnumMap-rakenteita toistensa sisään ja mallintaa kahden enum-tyypin mukaan avainnetun matriisin, kuten tilasiirtymätaulukon.

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

Oikean tyypin valitseminen

Nyrkkisääntö:

  • Jos avaimet ovat enum-vakioita ja tarvitsette kartan, käyttäkää EnumMapia.
  • Jos tarvitsette enum-tyyppien joukon, käyttäkää EnumSetiä.
  • Jos avaimet ovat mielivaltaisia olioita, käyttäkää HashMapia.
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);
    }
}

Pikatesti

Testatkaa EnumMap-tietämystänne.

Kertaus

Opitte EnumMapista:

  • Enum-vakioilla avainnettu taulukkopohjainen Map.
  • Konstruktori ottaa avainten Class-olion; null-avaimia ei sallita.
  • Iterointi tapahtuu määrittelyjärjestyksessä.
  • Turvallinen ja nopea korvaaja ordinal-arvon perusteella indeksoiduille taulukoille.

Olette suorittaneet edistyneen enum-kurssin.

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

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
104
Oppitunnit
374

Usein kysytyt kysymykset

Onko oppitunti ”EnumMap” ilmainen?

Kyllä – oppitunnin ”EnumMap” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”EnumMap”?

Tehokkaat enum-avaimiset kartat. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”EnumMap”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?

Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Enumit kenttien ja metodien kanssa
  2. Abstraktit metodit enumeissa
  3. EnumSet
  4. EnumMap
← Takaisin: Java Academy