Why would I need a collection Of Enums? Consider that we do have a simple enum:
One scenario I can think of is when we want to work with a generic set of enums - say code that simply displays a set. We couldn't do that cleanly with the values method as it returns arrays of a type. But then I could cast it to an object array and still pull it of
The RegularEnumSet works on the concepts of bit manipulation where a single bit in a 64 bit variable ( a long value) indicates if a particular enum exists in the set or not.So remove() or add() or removeAll() or contains() are all reduced to very fast bit manipulations. As we are working with 64 bits, the RegularEnumSet can obviously only be used for enums with a most 64 values. For larger enums we have the JumboEnumSet. Now that we know its advantages lets us look at some of the API available in EnumSet.
public enum Rating {Now if I want to get all the values I would call the Rating.values method. This would give me an array of Enums. Any reason why I would want a set of the same ?
TOP, GOOD, PASSABLE, BAD, POOR, FAIL
}
One scenario I can think of is when we want to work with a generic set of enums - say code that simply displays a set. We couldn't do that cleanly with the values method as it returns arrays of a type. But then I could cast it to an object array and still pull it of
publicstatic void display(Object[] enums) {lets just say I want to work with sets of enums. Maybe I need the additional power of the Collections API. The way to do this would be something like:
System.out.print("values are ");
for (Object object : enums) {
System.out.print(object + ", ");
}
System.out.println(" Size : " + enums.length);
}
Set<Rating> ratingSet = new HashSet<Rating>(Rating.values().length);Since enums are similar to a grouping of compile time constants, the JRE has created certain collections optimized for used with enums. One of these is the EnumSet. (The above ramblings were an attempt to come up with a use case for these collections. Sigh.) From the class comments:
Collections.addAll(ratingSet, Rating.values());
Enum sets are represented internally as bit vectors. This representationConsider the add method of HashSet:
is extremely compact and efficient. The space and time performance of
this class should be good enough to allow its use as a high-quality,
typesafe alternative to traditional int-based "bit flags".
public boolean add(E e) {This implementation adds the entries to a map. But now consider the same method from RegularEnumSet:
return map.put(e, PRESENT) == null;
}
public boolean add(E e) {As seen above there is no attempt to add the enum to the set. Instead a certain bit value is updated.
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum) e).ordinal());
return elements != oldElements;
}
The RegularEnumSet works on the concepts of bit manipulation where a single bit in a 64 bit variable ( a long value) indicates if a particular enum exists in the set or not.So remove() or add() or removeAll() or contains() are all reduced to very fast bit manipulations. As we are working with 64 bits, the RegularEnumSet can obviously only be used for enums with a most 64 values. For larger enums we have the JumboEnumSet. Now that we know its advantages lets us look at some of the API available in EnumSet.
publicstatic void main(String[] args) {The output is as below:
// EnumSet is abstract.
System.out.println("All available values are : " + EnumSet.allOf(Rating.class));
EnumSet<Rating> ratings = EnumSet.noneOf(Rating.class);
System.out.println("Is bad added ? " + ratings.contains(Rating.BAD));
ratings.add(Rating.BAD);
System.out.println("Is bad added ? " + ratings.contains(Rating.BAD));
System.out.println("A set of values except BAD " + EnumSet.complementOf(ratings));
System.out.println("A set of Positive values : " + EnumSet.range(Rating.TOP, Rating.PASSABLE));
System.out.println("A set of select values : " + EnumSet.of(Rating.TOP, Rating.PASSABLE));
}
All available values are : [TOP, GOOD, PASSABLE, BAD, POOR, FAIL]As seen, The EnumSet class provides a series of static methods to create the EnumSet. Its package scoped constructor is as below:
Is bad added ? false
Is bad added ? true
A set of values except BAD [TOP, GOOD, PASSABLE, POOR, FAIL]
A set of Positive values : [TOP, GOOD, PASSABLE]
A set of select values : [TOP, PASSABLE]
EnumSet(Class<E>elementType, Enum[] universe) {
//..code
}
As seen the class specifically accepts the Enum type and also an array of all enum values. So do not try to mix Enum values Also the iterator that we receive from above set will include in which the enum constants in the order they are declared.