0Pricing
Java Academy · บทเรียน

EnumMap

แผนที่ที่ใช้อีนัมเป็นคีย์อย่างมีประสิทธิภาพ

EnumMap เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

EnumMap คืออะไร

EnumMap เป็น Map เฉพาะทางที่มีคีย์เป็นค่าคงที่จากอีนัมชนิดเดียวกัน

ภายในมีอาร์เรย์ธรรมดารองรับ โดยใช้ออร์ดิของค่าคงที่เป็นดัชนี จึงค้นหาและเพิ่มข้อมูลได้รวดเร็วมากโดยไม่ต้องแฮช

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

ไม่อนุญาตให้ใช้คีย์ null

EnumMap ไม่อนุญาตให้ใช้คีย์ null คีย์ null จะทำให้เกิด NullPointerException

ค่า null ใช้งานได้ เช่นเดียวกับแมปชนิดอื่น

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 ช่วยหลีกเลี่ยงการตรวจสอบค่า null และ 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));
    }
}

EnumMaps ซ้อนกัน

คุณสามารถซ้อน EnumMaps เพื่อจำลองเมทริกซ์ที่ใช้คีย์จากอีนัมสองชนิด เช่น ตารางการเปลี่ยนสถานะ

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

การเลือกชนิดที่เหมาะสม

หลักทั่วไป:

  • หากคีย์เป็นค่าคงที่ของอีนัมและคุณต้องการแมป ให้ใช้ 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 ที่มีอาร์เรย์รองรับและใช้ค่าคงที่ของอีนัมเป็นคีย์
  • ตัวสร้างรับคลาสของคีย์ และไม่อนุญาตให้ใช้คีย์ null
  • วนซ้ำตามลำดับการประกาศ
  • สิ่งทดแทนอาร์เรย์ที่จัดทำดัชนีด้วย 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” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “EnumMap”

แผนที่ที่ใช้อีนัมเป็นคีย์อย่างมีประสิทธิภาพ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “EnumMap” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. อีนัมที่มีฟิลด์และเมธอด
  2. เมธอดนามธรรมในอีนัม
  3. EnumSet
  4. EnumMap
← กลับไปที่ Java Academy