From 947e8a3edc680f70358fad8aec1b9f7dde127a22 Mon Sep 17 00:00:00 2001
From: bungrudi <30967151+bungrudi@users.noreply.github.com>
Date: Fri, 2 Nov 2018 22:14:27 +0700
Subject: [PATCH] Guide to EnumMap
Issue: BAEL-2260
---
core-java-collections/pom.xml | 2 +-
.../java/com/baeldung/enummap/DummyEnum.java | 13 ++
.../enummap/EnumMapBenchmarkLiveTest.java | 119 +++++++++++++++
.../com/baeldung/enummap/EnumMapUnitTest.java | 144 ++++++++++++++++++
4 files changed, 277 insertions(+), 1 deletion(-)
create mode 100644 core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java
create mode 100644 core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java
create mode 100644 core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java
diff --git a/core-java-collections/pom.xml b/core-java-collections/pom.xml
index 39ddc17684..d3ef953e01 100644
--- a/core-java-collections/pom.xml
+++ b/core-java-collections/pom.xml
@@ -65,7 +65,7 @@
4.1
4.01
1.7.0
- 3.6.1
+ 3.11.1
7.1.0
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java b/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java
new file mode 100644
index 0000000000..906c820fa3
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/DummyEnum.java
@@ -0,0 +1,13 @@
+package com.baeldung.enummap;
+
+/**
+ * This enum is used for benchmarking, therefore has many values.
+ */
+public enum DummyEnum {
+ CCC_000,
+ CCC_001,CCC_002,CCC_003,CCC_004,CCC_005,CCC_006,CCC_007,CCC_008,CCC_009,CCC_010,
+ CCC_011,CCC_012,CCC_013,CCC_014,CCC_015,CCC_016,CCC_017,CCC_018,CCC_019,CCC_020,
+ CCC_021,CCC_022,CCC_023,CCC_024,CCC_025,CCC_026,CCC_027,CCC_028,CCC_029,CCC_030,
+ CCC_031,CCC_032,CCC_033,CCC_034,CCC_035,CCC_036,CCC_037,CCC_038,CCC_039,CCC_040,
+ CCC_041,CCC_042,CCC_043,CCC_044,CCC_045,CCC_046,CCC_047,CCC_048,CCC_049,
+}
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java
new file mode 100644
index 0000000000..997a8ba65b
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapBenchmarkLiveTest.java
@@ -0,0 +1,119 @@
+package com.baeldung.enummap;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({ Mode.AverageTime })
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+public class EnumMapBenchmarkLiveTest {
+
+ @State(Scope.Thread)
+ public static class BenchmarkState {
+ EnumMap enumMap = new EnumMap<>(DummyEnum.class);
+ HashMap hashMap = new HashMap<>();
+ TreeMap treeMap = new TreeMap<>();
+ int len = DummyEnum.values().length;
+ Random random = new Random();
+ int randomIndex;
+
+ @Setup(Level.Trial)
+ public void setUp() {
+ DummyEnum[] values = DummyEnum.values();
+ for (int i = 0; i < len; i++) {
+ enumMap.put(values[i], values[i].toString());
+ hashMap.put(values[i], values[i].toString());
+ treeMap.put(values[i], values[i].toString());
+ }
+ }
+
+ @Setup(Level.Invocation)
+ public void additionalSetup() {
+ randomIndex = random.nextInt(len);
+ }
+
+ }
+
+ @Benchmark
+ public int benchmark01_EnumMapPut(BenchmarkState s) {
+ s.enumMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_HashMapPut(BenchmarkState s) {
+ s.hashMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark01_TreeMapPut(BenchmarkState s) {
+ s.treeMap.put(DummyEnum.values()[s.randomIndex], DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_EnumMapGet(BenchmarkState s) {
+ s.enumMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_HashMapGet(BenchmarkState s) {
+ s.hashMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark02_TreeMapGet(BenchmarkState s) {
+ s.treeMap.get(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_EnumMapContainsKey(BenchmarkState s) {
+ s.enumMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_HashMapContainsKey(BenchmarkState s) {
+ s.hashMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark03_TreeMapContainsKey(BenchmarkState s) {
+ s.treeMap.containsKey(DummyEnum.values()[s.randomIndex]);
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_EnumMapContainsValue(BenchmarkState s) {
+ s.enumMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_HashMapContainsValue(BenchmarkState s) {
+ s.hashMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ @Benchmark
+ public int benchmark04_TreeMapContainsValue(BenchmarkState s) {
+ s.treeMap.containsValue(DummyEnum.values()[s.randomIndex].toString());
+ return ++s.randomIndex;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder().include(EnumMapBenchmarkLiveTest.class.getSimpleName()).threads(1).forks(0).shouldFailOnError(true).shouldDoGC(false).jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java
new file mode 100644
index 0000000000..d9d6cf2c39
--- /dev/null
+++ b/core-java-collections/src/test/java/com/baeldung/enummap/EnumMapUnitTest.java
@@ -0,0 +1,144 @@
+package com.baeldung.enummap;
+
+import org.junit.Test;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.AbstractMap.SimpleEntry;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class EnumMapUnitTest {
+ public enum DayOfWeek {
+ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
+ }
+
+ @Test
+ public void whenContructedWithEnumType_ThenOnlyAcceptThatAsKey() {
+ Map dayMap = new EnumMap<>(DayOfWeek.class);
+ assertThatCode(
+ () -> dayMap.put(TimeUnit.NANOSECONDS, "NANOSECONDS"))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenConstructedWithEnumMap_ThenSameKeyTypeAndInitialMappings() {
+ EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+
+ EnumMap activityMapCopy = new EnumMap<>(activityMap);
+ assertThat(activityMapCopy.size()).isEqualTo(2);
+ assertThat(activityMapCopy.get(DayOfWeek.MONDAY))
+ .isEqualTo("Soccer");
+ assertThat(activityMapCopy.get(DayOfWeek.TUESDAY))
+ .isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenEmptyMap_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap();
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Specified map is empty");
+ }
+
+ @Test
+ public void givenMapWithEntries_whenConstructedWithMap_ThenSucceed() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(DayOfWeek.TUESDAY, "Basketball");
+ EnumMap enumMap = new EnumMap<>(ordinaryMap);
+ assertThat(enumMap.size()).isEqualTo(2);
+ assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(enumMap.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");
+ }
+
+ @Test
+ public void givenMapWithMultiTypeEntries_whenConstructedWithMap_ThenException() {
+ HashMap ordinaryMap = new HashMap<>();
+ ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");
+ ordinaryMap.put(TimeUnit.MILLISECONDS, "Other enum type");
+ assertThatCode(() -> new EnumMap(ordinaryMap))
+ .isInstanceOf(ClassCastException.class);
+ }
+
+ @Test
+ public void whenPut_thenGet() {
+ Map activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.THURSDAY, null);
+ assertThat(activityMap.get(DayOfWeek.WEDNESDAY)).isEqualTo("Hiking");
+ assertThat(activityMap.get(DayOfWeek.THURSDAY)).isNull();
+ }
+
+ @Test
+ public void givenMapping_whenContains_thenTrue() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.containsValue("Hiking")).isFalse();
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();
+ assertThat(activityMap.containsValue("Hiking")).isTrue();
+
+ 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();
+ }
+
+ @Test
+ public void whenRemove_thenRemoved() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
+ assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();
+
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Hiking")).isEqualTo(false);
+ assertThat(activityMap.remove(DayOfWeek.MONDAY, "Soccer")).isEqualTo(true);
+ }
+
+ @Test
+ public void whenSubView_thenSubViewOrdered() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ Set keys = activityMap.keySet();
+ assertThat(keys)
+ .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY,DayOfWeek.THURSDAY);
+
+ assertThat(activityMap.entrySet())
+ .containsExactly(
+ new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
+ new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
+ new SimpleEntry(DayOfWeek.THURSDAY, "Karate"));
+ }
+
+ @Test
+ public void givenSubView_whenChange_thenReflected() {
+ EnumMap activityMap = new EnumMap(DayOfWeek.class);
+ activityMap.put(DayOfWeek.THURSDAY, "Karate");
+ activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
+ activityMap.put(DayOfWeek.MONDAY, "Soccer");
+
+ Collection values = activityMap.values();
+ assertThat(values).containsExactly("Soccer", "Hiking", "Karate");
+
+ activityMap.put(DayOfWeek.TUESDAY, "Basketball");
+ assertThat(values)
+ .containsExactly("Soccer", "Basketball", "Hiking", "Karate");
+
+ values.remove("Hiking");
+ assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
+ assertThat(activityMap.size()).isEqualTo(3);
+ }
+}