Skip to main content

Fun with EnumSet

Posted by mkarg on January 3, 2010 at 6:39 AM PST

Do you know EnumSet? No? Then you should take the time to look at this sample code. EnumSet allows writing of really eloquent Java source code. Run the following code and watch its result printed on the screen. Then check the below source code to find out how it works. The source code particulary makes use of (at least) the following features introduced in Java 5:

  • enum keyword
The enum keyword allows to define enumerations.
  • enum custom methods
Enumerations can have custom methods.
  • enum toString()
Enumerations provide an automatic implementation of toString() that returns the name of the enum value.
  • EnumSet.range()
This method returns a set of enumeration values created from a range of enumeration values.
  • EnumSet.allOf()
This method returns a set of enumeraton values that contain all values of the specified enumeration.
  • EnumSet.clone()
Create a complete copy of a set of enumeration values.
  • EnumSet.removeAll()
Subtract a set of enumeration values from another one.
  • EnumSet.size()
Gets the number of enumeration values in the set.
  • EnumSet iteration
You can iterate over a set of enumeration values using the for-each statement of Java 5.
  • String.format(), including automatic calling of .toString()
String.format() provides a cool way to format messages, and it automaticaly calls .toString() internally.
 import java.util.EnumSet;

public final class EnumSetSample {

private enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;

public static final EnumSet<Weekday> WORKDAYS = EnumSet.range(MONDAY, FRIDAY);

public final boolean isWorkday() {
return WORKDAYS.contains(this);
}

public static final EnumSet<Weekday> THE_WHOLE_WEEK = EnumSet.allOf(Weekday.class);
}

public static final void main(final String... argumgents) {
System.out.println("Work Schedule:");

for (final Weekday weekday : Weekday.THE_WHOLE_WEEK)
System.out.println(String.format("%d. On %s you " + (weekday.isWorkday() ? "have to work" : "can relax") + ".", weekday.ordinal() + 1, weekday));

System.out.println("Do I have to work the whole week?");

System.out.println(Weekday.WORKDAYS.containsAll(Weekday.THE_WHOLE_WEEK) ? "Yes, unfortunately." : "Certainly not.");

final EnumSet<Weekday> weekend = Weekday.THE_WHOLE_WEEK.clone();
weekend.removeAll(Weekday.WORKDAYS);

System.out.println(String.format("The weekend is %d days long.", weekend.size()));

}
}

 

Comments

Separator support is missing. Suppose you define the tokens, ...

Separator support is missing. Suppose you define the tokens, some of which are keywords. You do it by
tokens = enum {LPAREN, EOL, __KEYWORDS_START_HERE__,
IF, FOR, WHILE, ..., NULL
__KEYWORDS_END_HERE}
Now, you want to color keywords with special color. You do not want to iterate like

for (EnumSet.range(IF,NULL)) {

because suppose that somebody wants to add a new keyword. He immediately recognizes that he must put his keyword between __KEYWORDS_START_HERE__, and KEYWORDS_END. Suppose that he puts his keyword into the very beginning, before IF, or adds to the very end, after NULL. Despite this is very reasonable assumption, he will be surprised that his keyword is not highlighted because it is not in the IF-NULL range.

In VHDL, we have E'succ(x), E'pred(x) and E'leftof(x)/E'rightof(x), which exactly return the elements before and after x for the enum E. This is what I seem missing in the Java.

a caveat about EnumSet

Hi Mark, The JavaDoc for EnumSet advertizes it as a superior alternative to bitmasks.
Rather unfortunately, EnumSet is modifiable!
Therefore, declaring final static instances of EnumSet as a direct substitute for bitmasks cannot be recommended (as they could be modified by external code).
Instead, one needs to wrap the EnumSet in a "normal" java.util.Set like this:
public static final Set<Weekday> WORKDAYS = Collections.unmodifiableSet(EnumSet.range(MONDAY, FRIDAY));

Bitmask Cannot be modified

Hi, I am new to Java. So Can you please explain me why Bitmasks couldnt be modified? Regards Udhaya

Some classes just are not finished

You are right. It is a pity that there are some classes in the JRE that just seem to be not finished.