Panduan untuk EnumMap

1. Gambaran keseluruhan

EnumMap adalah pelaksanaan Peta yang secara eksklusif mengambil Enum sebagai kuncinya.

Dalam tutorial ini, kita akan membincangkan sifatnya, kes penggunaan umum dan kapan kita harus menggunakannya.

2. Penyediaan Projek

Bayangkan keperluan sederhana di mana kita perlu memetakan hari dalam seminggu dengan sukan yang kita mainkan pada hari itu:

Monday Soccer Tuesday Basketball Wednesday Hiking Thursday Karate 

Untuk ini, kita boleh menggunakan enum:

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

Yang akan kita lihat tidak lama lagi akan menjadi kunci peta kita.

3. Penciptaan

Untuk mula menerokai EnumMap , pertama kita perlu membuat contoh:

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

Dan inilah perbezaan pertama kami dengan sesuatu yang lebih biasa, seperti HashMap . Perhatikan bahawa dengan HashMap , parameterisasi jenis sudah mencukupi, yang bermaksud kita dapat menghilangkan HashMap baru (). Walau bagaimanapun, EnumMap memerlukan jenis kunci dalam konstruktor .

3.1. Pembina Salinan EnumMap

EnumMap juga dihantar dengan dua pembina salinan. Yang pertama mengambil EnumMap yang 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. Pembina Salinan Peta

Atau, jika kita mempunyai Peta kosong yang kuncinya adalah enum, kita juga boleh 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 bahawa peta tidak boleh kosong sehingga EnumMap dapat menentukan jenis kunci dari entri yang ada.

Sekiranya peta yang ditentukan mengandungi lebih daripada satu jenis enum, konstruktor akan membuang ClassCastException .

4. Menambah dan Mengambil Elemen

Setelah membuat EnumMap , kita dapat menambahkan sukan kita menggunakan kaedah put () :

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

Dan untuk mendapatkannya, kita boleh menggunakan get () :

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

5. Memeriksa Elemen

Untuk memeriksa apakah kami mempunyai pemetaan yang ditentukan untuk hari tertentu, kami menggunakan mengandungKey () :

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

Dan, untuk memeriksa sama ada sukan tertentu dipetakan ke mana-mana kunci yang kami gunakan mengandungValue () :

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

5.1. batal sebagai Nilai

Sekarang, null adalah nilai semantik yang sah untuk EnumMap .

Mari kaitkan null dengan "tidak melakukan apa-apa", dan memetakannya hingga 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. Mengeluarkan Elemen

Untuk memetakan hari tertentu, kami hanya membuangnya () :

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

Seperti yang dapat kita perhatikan, remove (key) mengembalikan nilai sebelumnya yang berkaitan dengan kunci, atau null jika tidak ada pemetaan untuk kunci.

Kita juga boleh memilih untuk memetakan peta tertentu hanya jika hari itu dipetakan ke aktiviti 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) membuang entri untuk kunci yang ditentukan hanya jika kunci pada masa ini dipetakan ke nilai yang ditentukan.

7. Paparan Koleksi

Sama seperti peta biasa, dengan EnumMap mana pun , kita boleh mempunyai 3 pandangan atau subkumpulan yang berbeza.

First, let's create a new map of our activities:

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

7.1. values

The first view of our activity map is values() which, as the name suggests, returns all the values in the map:

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

Note here that EnumMap is an ordered map. It uses the order of the DayOfWeek enum to determine the order of the entries.

7.2. keySet

Similarly, keySet() returns a collection of the keys, again in enum order:

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

7.3. entrySet

Lastly, entrySet() returns the mapping in pairs of key and value:

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

Ordering in a map can certainly come in handy, and we go into more depth in our tutorial that compares TreeMap to HashMap.

7.4. Mutability

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

Dalam artikel ini, kami telah meneroka pelaksanaan EnumMap pada antara muka Peta . Apabila bekerja dengan Enum sebagai kunci, EnumMap dapat berguna.

Kod sumber lengkap untuk semua contoh yang digunakan dalam tutorial ini boleh didapati dalam projek GitHub.