Have you ever used Java standard class EnumSet in real-life applications? Me neither. Nevertheless, it can be useful in some cases.
EnumSet is an abstract Set which can hold enum values only. And if you are about to store enum values in a Set, you should always use EnumSet because it is usually faster and takes less memory. These benefits are achieved by storing data as a bit vector in one of two EnumSet implementations:
-
longbit vector inRegularEnumSetfor enum types with 64 or fewer enum constants, -
long[]bit vector inJumboEnumSetfor enum types with more than 64 elements.
But enough talking, let's see it in action!
Here we have an enum of quotes:
@Getter
@AllArgsConstructor
public enum Quote {
DONT_PANIC("Don't Panic."),
THE_ANSWER("42"),
TOWEL("A towel is about the most massively useful thing an interstellar hitchhiker can have."),
SO_LONG("So long, and thanks for all the fish."),
;
private final String value;
}
Here is how we can create EnumSet:
EnumSet<Quote> allQuotes = EnumSet.allOf(Quote.class);
EnumSet<Quote> noQuotes = EnumSet.noneOf(Quote.class);
EnumSet<Quote> twoQuotes = EnumSet.of(Quote.DONT_PANIC, Quote.TOWEL);
EnumSet<Quote> threeQuotes = EnumSet.range(Quote.DONT_PANIC, Quote.TOWEL);
EnumSet<Quote> sameThreeQuotes = EnumSet.complementOf(EnumSet.of(Quote.SO_LONG));
allQuotes contains all the enum elements, while noQuotes is empty.
twoQuotes contains two listed elements, while both threeQuotes and sameThreeQuotes contain the set of the first three elements of the Quotes enum.
Now, you can use all the standard operations with these sets, e.g. add, remove, contains, etc.
Dream your code, code your dream.
Top comments (2)
EnumSet handy API probably the only legit reason to prefer it over Set.
This is called premature optimisation, and developers should consider speed and memory consumption only if it’s hot place in the app, otherwise it’s just bringing additional complexity which we could avoid. The only exception of this rule is mobile app.
Setis an interface, whileEnumSetis an implementation of that interface. So I'm confused about your statement concerning preference of one over the other. They are not alternatives of each other.Second, your quote from the post cut off a key part of the author's original sentence. The author of the post isn't claiming that you should always use
EnumSetin general. They are claiming that strictly for the case of a set of enum values.Also, choosing to use
EnumSetfor a set of enum values, rather than let's say aHashSetor aTreeSet, is not an example of premature optimization. It is a sound choice of data structure for the specified context. It also does not increase code complexity at all. It implements the exact same interface,Set, as the alternatives. Other than instantiating an instance ofEnumSetrather than an instance of one of the otherSetimplementations, all other code would be the same. No additional code complexity caused by usingEnumSetvs any of the alternatives.Premature optimization would be if he was suggesting using a
longdirectly and using bitwise operations for adding elements, removing elements, and checking for containment, etc in order to avoid method calls. That would add unnecessary code complexity for no substantive gain. But that isn't what he is suggesting. Choosing to use anEnumSetto represent a set of values of an enum type is just making an informed and wise choice of data structure from among the available options for doing so.