Mục lục
EnumMap là một Map implementation được thiết kế để làm việc với kiểu dữ liệu Enum trong Java. Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu về nó, cũng như một số trường hợp sử dụng cơ bản, và khi nào thì nên sử dụng EnumMap.
Project Setup
Hãy tưởng tượng một yêu cầu đơn giản trong đó chúng ta cần lập bản đồ các ngày trong tuần với môn thể thao chúng ta chơi vào ngày đó:
Monday Soccer Tuesday Basketball Wednesday Hiking Thursday Karate
Do vậy, chúng ta cần cần tạo một Enum
public enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
Khởi tạo EnumMap
Để khởi tạo EnumMap với enum là DayOfWeek enum
EnumMap<DayOfWeek, String> activityMap = new EnumMap<>(DayOfWeek.class); activityMap.put(DayOfWeek.MONDAY, "Soccer");
Đây là điểm khác biệt đầu tien so với những Map implementation khác như HashMap. Lưu ý rằng với HashMap chúng ta có thể khởi tạo new HashMap<>(). Tuy nhiên, EnumMap yêu cầu kiểu dữ liệu của key trong quá trình khởi tạo.
EnumMap copy constructor
EnumMap cũng có hai trình tạo bản sao. Đầu tiên lấy một EnumMap khác: Đầu tiên lấy một EnumMap khác
EnumMap<DayOfWeek, String> activityMap = new EnumMap<>(DayOfWeek.class); activityMap.put(DayOfWeek.MONDAY, "Soccer"); activityMap.put(DayOfWeek.TUESDAY, "Basketball"); EnumMap<DayOfWeek, String> activityMapCopy = new EnumMap<>(activityMap); assertThat(activityMapCopy.size()).isEqualTo(2); assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer"); assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball")
Map Copy Constructor
Map<DayOfWeek, String> ordinaryMap = new HashMap(); ordinaryMap.put(DayOfWeek.MONDAY, "Soccer"); EnumMap enumMap = new EnumMap(ordinaryMap); assertThat(enumMap.size()).isEqualTo(1); assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
Lưu ý rằng Map không được rỗng tất là nó phải chứa ít nhất một phần tử để EnumMap có thể xác định được kiểu dữ liệu của key từ một phần tử đã tồn tại trong Map.
Thêm và truy xuất phần tử trong EnumMap
Sau khi khởi tạo một EnumMap, chúng ta có thể thêm phần tử vào thông qua put() method.
activityMap.put(DayOfWeek.MONDAY, "Soccer");
Và để truy xuất một phần tử trong EnumMap chúng ta phải sử dụng đến get() method nhận vào một key và trả về value tương ứng.
assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
Kiểm tra phần tử
Để kiểm tra xem chúng ta có một ánh xạ được xác định cho một ngày cụ thể hay không, chúng tôi sử dụng hàm containsKey ():
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking"); assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();
Và để kiểm tra có chứa một value bất kỳ hay không chúng ta có thể sử dụng containsValue().
assertThat(activityMap.containsValue("Hiking")).isTrue();
Value Null
Một key có chứa value là NULL được xem là hợp lệ trong EnumMap
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse(); assertThat(activityMap.containsValue(null)).isFalse(); activityMap.put(DayOfWeek.SATURDAY, null); assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue(); assertThat(activityMap.containsValue(null)).isTrue();
Xoá phần tử
Để xoá một phần tử ra khỏi EnumMap chúng ta có thể sử dụng remove() method
activityMap.put(DayOfWeek.MONDAY, "Soccer"); assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer"); assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();
Như chúng ta có thể quan sát, remove (key) trả về giá trị trước đó được liên kết với key hoặc null nếu không có ánh xạ cho key.
Chúng ta cũng có thể xoá dựa vào một cặp key-value cụ thể tương ứng trong EnumMap.
activityMap.put(DayOfWeek.Monday, "Soccer"); assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false); assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true);
Method remove (key, value) chỉ xóa phần tử nếu tồn tại một phần có key và value tương ứng với tham số truyền vào.
Collection Views
Để liệt kê một danh sách các key hoặc value trong EnumMap chúng ta có thể thực thi bằng những cách được mô tả ở các phần sau. Trước tiên, chúng ta cần khởi tạo một EnumMap dùng cho các ví dụ bên dưới.
EnumMap<DayOfWeek, String> activityMap = new EnumMap(DayOfWeek.class); activityMap.put(DayOfWeek.THURSDAY, "Karate"); activityMap.put(DayOfWeek.WEDNESDAY, "Hiking"); activityMap.put(DayOfWeek.MONDAY, "Soccer");
values
Hàm values() trả về tất cả các value được lưu trữ trong EnumMap.
Collection values = dayMap.values(); assertThat(values) .containsExactly("Soccer", "Hiking", "Karate");
Lưu ý ở đây rằng EnumMap là một Map có thứ tự, Nó sử dụng thứ tự của enum DayOfWeek để xác định thứ tự của các phần tử.
keySet
Tương tự, keySet() trả về danh sách các key trong EnumMap, thứ tự trả về được sắp xếp theo Enum.
Set keys = dayMap.keySet(); assertThat(keys) .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);
entrySet
Cuối cùng entrySet trả về danh sách cặp key-value trong EnumMap
assertThat(dayMap.entrySet()) .containsExactly( new SimpleEntry(DayOfWeek.MONDAY, "Soccer"), new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"), new SimpleEntry(DayOfWeek.THURSDAY, "Karate") );
Mutability
Bây giờ, hãy nhớ rằng bất kỳ thay đổi nào chúng ta thực hiện trong EnumMap sẽ ảnh hưởng đến thứ tự sắp xếp của các phần tử.
Ví dụ khi chúng ta thêm DayOfWeek.TUESDAY vào EnumMap thì nó sẽ được xếp sau DayOfWeek.MONDAY và DayOfWeek.WEDNESDAY nhưng lại trước DayOfWeek.THURSDAY.
activityMap.put(DayOfWeek.TUESDAY, "Basketball"); assertThat(values) .containsExactly("Soccer", "Basketball", "Hiking", "Karate");
Khi nào nên sử dụng EnumMap
Hiệu năng
Sử dụng Enum làm key giúp bạn có thể thực hiện một số tối ưu hóa hiệu suất bổ sung, chẳng hạn như tính toán băm nhanh hơn vì tất cả các key khả thi đều được biết trước.
Sử dụng Enum làm key giúp EnumMao chỉ cần sử dụng một mảng thuần tuý trong Java để lưu trữ và truy xuất trong khi các Map implementation khác cần một cấu trúc khác phức tạp hơn để lưu trữ các key có kiểu generic type. Ví dụ, HashMap cần một cấu trúc dữ liệu phức tạp và một logic lưu trữ và truy xuất phức tạp hơn đáng kể để phục vụ cho khả năng xảy ra xung đột băm.
Chức năng
Ngoài ra, như chúng ta đã thấy, EnumMap là một Map có thứ tự, trong đó các dữ liệu của nó sẽ được sắp xếp theo thứ tự enum. Để có được hành vi tương tự cho các tình huống phức tạp hơn, chúng ta có thể TreeMap và LinkedHashMap.
Kết bài
Trong bài viết này, chúng ta đã khám phá cách triển khai EnumMap của Map interface Khi làm việc với Enum làm key, EnumMap có thể hữu ích trong những trường hợp như vậy.
Nguồn tham khảo
https://www.baeldung.com/java-enum-map