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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ