DEV Community

Cover image for [Tiny] The Least Known Set in Java: EnumSet
Petr Filaretov
Petr Filaretov

Posted on

[Tiny] The Least Known Set in Java: EnumSet

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:

  • long bit vector in RegularEnumSet for enum types with 64 or fewer enum constants,
  • long[] bit vector in JumboEnumSet for 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;
}
Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
nick318 profile image
Nikita

EnumSet handy API probably the only legit reason to prefer it over Set.

you should always use EnumSet because it is usually faster and takes less memory

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.

Collapse
 
cicirello profile image
Vincent A. Cicirello • Edited

Set is an interface, while EnumSet is 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 EnumSet in general. They are claiming that strictly for the case of a set of enum values.

Also, choosing to use EnumSet for a set of enum values, rather than let's say a HashSet or a TreeSet, 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 of EnumSet rather than an instance of one of the other Set implementations, all other code would be the same. No additional code complexity caused by using EnumSet vs any of the alternatives.

Premature optimization would be if he was suggesting using a long directly 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 an EnumSet to 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.