Reputation: 101
I've been reading up Java recently. So I have a enum below that acts as a map with key "JESSIE" and value "My favorite cat".
So why does anyone need to use EnumMap? Thanks
public enum Cat {
JESSIE("My favorite cat");
private String description;
Cat(String description){
this.description = description;
}
}
Upvotes: 6
Views: 4215
Reputation: 73558
The enum
is the key in an EnumMap
, and therefore those two things are completely different. You have no way of knowing all the kinds of things you may want to associate with your cats.
The description
may be an inherent part of Cat
, but you might want to associate cats with their servants, or where they (currently) live or what their preferred meal (currently) is.
EnumMap<Cat, Human> catsServant;
EnumMap<Cat, House> catsHome;
EnumMap<Cat, Meal> catsFood;
Since you don't need to modify Cat
to associate it with another object, it makes it a lot easier to use, and your enum would become huge if you filled it with all possible things you might want to associate your cats with.
A second issue is that enum
s are singletons, which means that if you were to put mutable state (strongly discouraged!) in your Cat
by adding a setDescription(String)
method, it will change that globally in your program. That may not matter for simple programs or a simple property like description
, but it does matter when you have more complex code.
Now a more realistic example. The JDK TimeUnit
enum has values such as MINUTE
, and the creators couldn't have known of all the possible things that people might want to associate with them. However with an EnumMap
I can provide a translation to my native language as follows:
EnumMap<TimeUnit, String> xlate = new EnumMap<>(TimeUnit.class);
xlate.put(TimeUnit.MINUTE, "Minuutti");
xlate.put(TimeUnit.SECOND, "Sekunti");
TimeUnit
isn't my class, so I can't edit it to include those translations, and it would be the wrong place anyway.
A related question is why is there a special EnumMap
, since you can also use a normal map, such as HashMap<Cat, Human>
.
Upvotes: 7
Reputation: 31878
The primary reason behind this would be to design the classes in such a way that it holds the attributes that represent its entity and not which it would require a mapping with while querying.
As an example, consider another class Human
as follows
@AllArgsConstructor
static class Human {
String name;
}
Now you could have looked for a Cat
to its owner mapping, but how much of a sense would it make to keep the entire Human
object referenced for such a mapping? Despite the fact, that you could keep such a reference, what's helpful for the purpose of query ability is to keep such a reference in an additional data structure EnumMap
in this case -
EnumMap<Cat, Human> enumMap = new EnumMap<>(Cat.class);
enumMap.put(Cat.JESSIE, new Human("naman"));
enumMap.put(Cat.LUCY, new Human("user"));
Upvotes: 3