Wednesday, 14 October 2015

EnumSet in Java

EnumSet in Java is a specialized set implementation for use with enum types. EnumSet was introduced in Java 5 along with the Enum.

According to Java docs "Enum sets are represented internally as bit vectors. This representation 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." Even bulk operations (such as containsAll and retainAll) should run very quickly if their argument is also an enum set."

How EnumSet works

One of the things to note about EnumSet is that it is an abstract class and uses factory methods to create objects. There are two concrete implementations of EnumSet -

  • RegularEnumSet
  • JumboEnumSet
Any of these two classes can't be instantiated directly by the user as these classes have default (package-private) access.

Depending upon the size of the Enum any of these classes is instantiated by the EnumSet class itself. If Enum has 64 or fewer enum constants then RegularEnumSet is used otherwise JumboEnumSet.

Example code using EnumSet

Since EnumSet can be used with an enum type so it provides use cases where some logic has to be used on the enum constants or EnumSet can be used instead of bit fields as explained in Effective Java.

Here I am creating an enum of weekdays and performing some logic to see whether it's a working day or not. Note how the EnumSet is created using the static factory methods of the EnumSet class and how methods provided by Set (for iteration, contains) are used for logic.

public class EnumSetDemo {
    // Enum
    private enum WeekDay {
         MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    }
    public static void main(String[] args) {
        // Creating EnumSet using range
        EnumSet<WeekDay> weekDaySet = EnumSet.range(
                    WeekDay.MONDAY, WeekDay.FRIDAY);
        // Creating EnumSet using complementOf method, The created 
        // set will contain all elements of the Enum not
        // contained in the specified set
        EnumSet<WeekDay> weekEndSet = EnumSet.complementOf(weekDaySet);
        
        //Another way of Creating EnumSet using of Method
        /*EnumSet<WeekDay> weekEndSet = EnumSet.of(
                    WeekDay.SATURDAY, WeekDay.SUNDAY);*/
        System.out.println("Using for each");
        // Iterating EnumSet
        for(WeekDay day : weekDaySet){
            System.out.println("Day - " + day);
        }
        
        System.out.println("Using itertor");
        Iterator<WeekDay> itr = weekEndSet.iterator();
        while(itr.hasNext()){
            System.out.println("Day - " + itr.next());
        }
        
        System.out.println("Need to work ? " + 
                    isWorkingDay(weekDaySet, WeekDay.MONDAY));
        System.out.println("Need to work ? " + 
                isWorkingDay(weekDaySet, WeekDay.SATURDAY));
    }
    private static boolean isWorkingDay(Set<WeekDay> daysSet, WeekDay day){    
        return daysSet.contains(day);
        
    }
}

Output

Using for each
Day - MONDAY
Day - TUESDAY
Day - WEDNESDAY
Day - THURSDAY
Day - FRIDAY
Using itertor
Day - SATURDAY
Day - SUNDAY
Need to work ? true
Need to work ? false

Nulls are not permitted

Null elements are not permitted in an EnumSet. Any attempt to insert a null element will throw NullPointerException.

Iteration of EnumSet

The iterator returned by the iterator method traverses the elements in their natural order (the order in which the enum constants are declared). The returned iterator is weakly consistent: it will never throw ConcurrentModificationException and it may or may not show the effects of any modifications to the set that occur while the iteration is in progress. Note that example of Iteration using iterator is already there in the example code.

EnumSet is not synchronized

EnumSet is not synchronized. If multiple threads access an enum set concurrently, and at least one of the threads modifies the set, it should be synchronized externally. It can be done using the synchronizedSet method of the Collections class.
Collections.synchronizedSet(java.util.Set<T>)

That's all for this topic EnumSet in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How HashSet works internally in Java
  2. LinkedHashSet in Java
  3. TreeSet in Java
  4. CopyOnWriteArraySet in Java
  5. How HashMap internally works in Java
  6. Java Collections interview questions

You may also like -

No comments:

Post a Comment