4

This seems like it would be a common question, but none of the items in the suggestion box exactly explained what I am wondering. In this link, everyone suggested using the enum type (which I've now researched, but never used prior). I was about to suggest simply using a HashMap and read the answers to see if the Enum ( http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html ) was ,in fact, a better answer. According to that link on oracle, "You should use enum types any time you need to represent a fixed set of constants." So, it is.

My question is... why? Is it more of forming a contract that they will not change? Is it a shorter way of getting some class functionality? How's the performance? Why is this any different than just defining the constants in the same class?

Thank you!

Community
  • 1
  • 1
Andrew Campbell
  • 17,665
  • 2
  • 16
  • 25

6 Answers6

6

Type safety is indeed a good reason: when you pass a String to a method, it can be anything. If you pass an enum, you are sure it is one of the legal values. enums are good if the set of possibilities is limited. HashMaps are good if you need to extend the values.

PhiLho
  • 40,535
  • 6
  • 96
  • 134
4

Enum instances are objects, encapsulating data and behaviour just like any other object. By passing enum instances around, anyone can call its methods. If you pass Map keys as Strings, for example, you can't do anything useful with the key. Moreover, the code is less type-safe, and less self-documenting, since the String could very well be something completely different from what it's supposed to be.

What's the most readable?

public int countDays(Set<Month> months, int year) {
    int count = 0;
    for (Month month : months) {
        count += month.getDays(year);
    }
    return count;
}

or

public int countDays(Set<String> months, int year) {
    int count = 0;
    for (String month : months) {
        int days = monthMap.get(month);
        if (month.equals(Months.FEBRUARY)) {
            days = computeDaysInFebruary(year);
        }
        count += days;
    }
    return count;
}

What if I pass something other than a month name in the set?

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
4

Enums are a very limited datatype that let you restrict possible values to a set and avoid others at compile time, so if you make a mistake it won't even compile. HashMap would let you insert a lot of non valid values, with effort they can be detected at runtime, but of course it will compile anyway.

Hernán Eche
  • 6,529
  • 12
  • 51
  • 76
2

All the reasons you said are pretty much correct.

An enum is more efficient as is it stored as an immutable list of values, and doesn't have to support as many operations as dictionary would. Additionally, an enum instance is just just stored internally as a single number and can be used exactly as if you had you defined your own list of "static final ints".

Additionally, they add type safety, as you don't have to worry about comparing an actual numerical value with an integer that is meant to represent some option; enums can only be compared with other enums. It also cannot be modified like a dictionary could be, so you know the values given at compile time will be the same at runtime.

But, I believe, the most important reason is the semantic value it adds. This is exactly the purpose of an enum - to define a set of unchanging options and limit yourself to only those options. If you use an enum, everyone will be able to understand intuitively what your are trying to do.

ceyko
  • 4,822
  • 1
  • 18
  • 23
2

A hashmap uses a good deal of memory, and even though you have constant time lookups and inserts, there is still a good level of processing that has to be done. The hash must be computed, then conflicting slots have to be resolved etc... Whereas an enumeration is stored usually in only 4 bytes, is type-safe, is efficient, and is obvious to other programmers what you are using it for.

Another benefit is that you can easily use bit arithmetic between enumeration values to represent others. The windows API does this quite frequently.

Jonathan Henson
  • 8,076
  • 3
  • 28
  • 52
0

In my opinion, they are just faster to declare and use, and, asn oracle says, they are better for constants. Enums can not be modified, so I am guessing their resource use is smaller.