Panduan untuk EnumMap

1. Ikhtisar

EnumMap adalah implementasi Peta yang secara eksklusif menggunakan Enum sebagai kuncinya.

Dalam tutorial ini, kita akan membahas propertinya, kasus penggunaan umum, dan kapan kita harus menggunakannya.

2. Pengaturan Proyek

Bayangkan persyaratan sederhana di mana kita perlu memetakan hari-hari dalam seminggu dengan olahraga yang kita mainkan pada hari itu:

Monday Soccer Tuesday Basketball Wednesday Hiking Thursday Karate 

Untuk ini, kita bisa menggunakan enum:

public enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

Yang akan segera kita lihat akan menjadi kunci untuk peta kita.

3. Penciptaan

Untuk mulai menjelajahi EnumMap , pertama-tama kita perlu membuatnya :

EnumMap activityMap = new EnumMap(DayOfWeek.class); activityMap.put(DayOfWeek.MONDAY, "Soccer"); 

Dan inilah perbedaan pertama kami dengan sesuatu yang lebih umum, seperti HashMap . Perhatikan bahwa dengan HashMap , parameterisasi tipe sudah cukup, artinya kita bisa lolos dengan HashMap () baru. Namun, EnumMap membutuhkan tipe kunci dalam konstruktor .

3.1. Pembuat Salinan EnumMap

EnumMap juga dikirimkan dengan dua konstruktor salinan. Yang pertama mengambil EnumMap lain :

EnumMap activityMap = new EnumMap(DayOfWeek.class); activityMap.put(DayOfWeek.MONDAY, "Soccer"); activityMap.put(DayOfWeek.TUESDAY, "Basketball"); EnumMap activityMapCopy = new EnumMap(dayMap); assertThat(activityMapCopy.size()).isEqualTo(2); assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer"); assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");

3.2. Pembuat Salinan Peta

Atau, jika kita memiliki Map yang tidak kosong yang kuncinya adalah enum, maka kita juga bisa melakukannya:

Map 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");

Perhatikan bahwa peta tidak boleh kosong sehingga EnumMap dapat menentukan jenis kunci dari entri yang sudah ada.

Jika peta yang ditentukan berisi lebih dari satu jenis enum, konstruktor akan menampilkan ClassCastException .

4. Menambah dan Mengambil Elemen

Setelah membuat instance EnumMap , kita bisa menambahkan olahraga kita menggunakan metode put () :

activityMap.put(DayOfWeek.MONDAY, "Soccer");

Dan untuk mendapatkannya kembali, kita bisa menggunakan get () :

assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

5. Memeriksa Elemen

Untuk memeriksa apakah kita memiliki pemetaan yang ditentukan untuk hari tertentu, kita menggunakan containsKey () :

activityMap.put(DayOfWeek.WEDNESDAY, "Hiking"); assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();

Dan, untuk memeriksa apakah olahraga tertentu dipetakan ke kunci apa pun, kami menggunakan containsValue () :

assertThat(activityMap.containsValue("Hiking")).isTrue(); 

5.1. null sebagai Nilai

Sekarang, null adalah nilai yang valid secara semantik untuk EnumMap .

Mari kaitkan null dengan "tidak melakukan apa-apa", dan petakan ke hari Sabtu:

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

6. Menghapus Elemen

Untuk menghapus peta pada hari tertentu, kita cukup menghapus () itu:

activityMap.put(DayOfWeek.MONDAY, "Soccer"); assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer"); assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse(); 

Seperti yang bisa kita amati, remove (key) mengembalikan nilai sebelumnya yang terkait dengan kunci tersebut, atau null jika tidak ada pemetaan untuk kunci tersebut.

Kita juga bisa memilih untuk membatalkan peta hari tertentu hanya jika hari itu dipetakan ke aktivitas tertentu:

activityMap.put(DayOfWeek.Monday, "Soccer"); assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false); assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true); 

remove (key, value) menghapus entri untuk kunci yang ditentukan hanya jika kunci saat ini dipetakan ke nilai yang ditentukan.

7. Tampilan Koleksi

Sama seperti peta biasa, dengan EnumMap apa pun , kita dapat memiliki 3 tampilan atau sub-koleksi berbeda.

Pertama, mari buat peta baru dari aktivitas kita:

EnumMap activityMap = new EnumMap(DayOfWeek.class); activityMap.put(DayOfWeek.THURSDAY, "Karate"); activityMap.put(DayOfWeek.WEDNESDAY, "Hiking"); activityMap.put(DayOfWeek.MONDAY, "Soccer");

7.1. nilai-nilai

Tampilan pertama dari peta aktivitas kita adalah values ​​() yang, seperti namanya, mengembalikan semua nilai di peta:

Collection values = dayMap.values(); assertThat(values) .containsExactly("Soccer", "Hiking", "Karate"); 

Perhatikan di sini bahwa EnumMap adalah peta yang dipesan. Ini menggunakan urutan enum DayOfWeek untuk menentukan urutan entri.

7.2. keySet

Demikian pula, keySet () mengembalikan koleksi kunci, lagi dalam urutan enum:

Set keys = dayMap.keySet(); assertThat(keys) .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY); 

7.3. entrySet

Terakhir, entrySet () mengembalikan pemetaan dalam pasangan kunci dan nilai:

assertThat(dayMap.entrySet()) .containsExactly( new SimpleEntry(DayOfWeek.MONDAY, "Soccer"), new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"), new SimpleEntry(DayOfWeek.THURSDAY, "Karate") ); 

Memesan dalam peta pasti bisa berguna, dan kami membahas lebih dalam dalam tutorial kami yang membandingkan TreeMap dengan HashMap.

7.4. Mutabilitas

Now, remember that any changes we make in the original activity map will be reflected in any of its views:

activityMap.put(DayOfWeek.TUESDAY, "Basketball"); assertThat(values) .containsExactly("Soccer", "Basketball", "Hiking", "Karate"); 

And vice-versa; any changes we make the sub-views will be reflected in the original activity map:

values.remove("Hiking"); assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse(); assertThat(activityMap.size()).isEqualTo(3); 

Per EnumMap‘s contract with Map interface, the sub-views are backed by the original map.

8. When to Use EnumMap

8.1. Performance

Using Enum as key makes it possible to do some extra performance optimization, like a quicker hash computation since all possible keys are known in advance.

The simplicity of having enum as key means EnumMap only need to be backed up by a plain old Java Array with very simple logic for storage and retrieval. On the other hand, generic Map implementations need to cater for concerns related to having a generic object as its key. For example, HashMap needs a complex data structure and a considerably more complex storing and retrieval logic to cater for the possibility of hash collision.

8.2. Functionality

Also, as we saw, EnumMap is an ordered map, in that its views will iterate in enum order. To get similar behavior for more complex scenarios, we can look at TreeMap or LinkedHashMap.

9. Conclusion

Pada artikel ini, kami telah menjelajahi implementasi EnumMap dari antarmuka Peta . Saat bekerja dengan Enum sebagai kunci, EnumMap bisa berguna.

Kode sumber lengkap untuk semua contoh yang digunakan dalam tutorial ini dapat ditemukan di proyek GitHub.