Introduction
In this post, we will see what an EnumSet in Java is and when to use it. We will have a look at the various methods available as part of an EnumSet.
What is an EnumSet in Java
An EnumSet is a specialized Set implementation meant to be used with enum types. All the elements in an EnumSet are enum instances. Also, they must come from a single enum type. The type of the enum can be specified explicitly or implicitly (we will see how this is done).
Why EnumSet
We can use an EnumSet when we want to have a Set<SomeEnum>. Internally Enum sets are represented as bit vectors. This representation is more efficient than using a particular Set implementation like HashSet or a TreeSet. Hence, the time and the space complexity of an EnumSet should be at least as good as other Set implementations. Thus, as a rule of thumb, use an EnumSet when a Set of enum is needed.
Ordering
The iterator returned by an EnumSet traverses the elements (enum constants) in their natural order i.e., the order in which the enum constants are declared.
Implementation
There are two concrete implementations of an EnumSet namely RegularEnumSet and JumboEnumSet. The EnumSet class is an abstract class and does not have any public constructors. It has a set of public static methods (static factory methods) to create EnumSet instances. (Note, this is not the same as a factory method pattern)
- If the number of enum constants is less than or equal to 64, then a RegularEnumSet is returned.
- If the number of enum constants is more than 64, then a JumboEnumSet is returned.
Operations
Once we create an enum, we can perform all the operations supported by a Set. We will below look at the various options provided by an EnumSet for its creation.
EnumSet creation
It offers a lot of static factories to create an EnumSet. For our examples, we will use the Grade enum. It has one enum constant representing a range of score.
public enum Grade { S(91, 100), A(81, 90), B(71, 80), C(61, 70), D(51, 60), E(50, 50), F(0, 49); private int fromScore; private int toScore; Grade(int fromScore, int toScore) { this.fromScore = fromScore; this.toScore = toScore; } public int getFromScore() { return fromScore; } public int getToScore() { return toScore; } }
EnumSet.allOf
Signature: <E
extends
Enum<E>> EnumSet<E> allOf(Class<E> elementType)
It creates an EnumSet having all the enum elements from the specified enum type.
Set<Grade> allGrades = EnumSet.allOf(Grade.class); System.out.println(allGrades); //[S, A, B, C, D, E, F]
EnumSet.of
EnumSet in Java provides a set of static factories to create an EnumSet from an explicitly passed enum elements (overloadings of these method to support passing one through five enum constants). There is also a method that accepts a varargs of an enum. We can use this to pass an arbitrary number of elements.
Set<Grade> maxGrade = EnumSet.of(Grade.S); Set<Grade> topThreeGrades = EnumSet.of(Grade.S, Grade.A, Grade.B); Set<Grade> passGrades = EnumSet.of(Grade.S, Grade.A, Grade.B, Grade.C, Grade.D, Grade.E); Set<Grade> failGrades = EnumSet.of(Grade.F);
EnumSet.complementOf
<E
extends
Enum<E>> EnumSet<E> complementOf(EnumSet<E> s)
This handy method is used to create an EnumSet having the elements from an enum that are not contained in the specified set.
EnumSet<Grade> failGrades = EnumSet.of(Grade.F); Set<Grade> passGrades = EnumSet.complementOf(failGrades); //[S, A, B, C, D, E]
EnumSet.noneOf
Signature: <E
extends
Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
It creates an empty enum set with the specified enum type.
Set<Grade> emptyGrades = EnumSet.noneOf(Grade.class); System.out.println(emptyGrades); //[]
EnumSet.range
Signature: <E
extends
Enum<E>> EnumSet<E> range(E from, E to)
Set<Grade> gradesFrom61To90 = EnumSet.range(Grade.A, Grade.C); System.out.println(gradesFrom61To90); //[A, B, C]
EnumSet – copy and clone
Two other methods exist to create an EnumSet by copying an existing EnumSet or a Collection of an enum and by cloning an existing EnumSet.
Set<Grade> passGrades = EnumSet.of(Grade.S, Grade.A, Grade.B, Grade.C, Grade.D, Grade.E); Set<Grade> passGradesCopy = EnumSet.copyOf(passGrades); System.out.println(passGrades.equals(passGradesCopy)); //true EnumSet<Grade> failGrades = EnumSet.of(Grade.F); EnumSet<Grade> failGradesCloned = failGrades.clone(); System.out.println(failGrades.equals(failGradesCloned)); //true
Conclusion
In this article, we have learnt about what an EnumSet in Java is and when it can be used. We also covered the main creation methods available for creating an EnumSet with examples.