Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would enum be more useful than a HashMap in this situation?

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!

like image 310
Andrew Campbell Avatar asked Dec 09 '22 18:12

Andrew Campbell


2 Answers

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.

like image 111
PhiLho Avatar answered Dec 11 '22 09:12

PhiLho


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?

like image 32
JB Nizet Avatar answered Dec 11 '22 07:12

JB Nizet