Tuesday, April 20, 2021

EnumSet in Java With Examples

EnumSet in Java is a specialized set implementation for use with enum types. EnumSet was introduced in Java 5 along with the Enum. All of the elements stored in an EnumSet must, explicitly or implicitly, come from a single enum type that is specified while creating the set. All basic operations of the EnumSet execute in constant time. They are likely (though not guaranteed) to be much faster than their HashSet counterparts.

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 in Java

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 in Java-

  • RegularEnumSet- Private implementation class for EnumSet, for "regular sized" enum types
  • JumboEnumSet- Private implementation class for EnumSet, for "jumbo" enum types (i.e., those with more than 64 elements).
Both of these 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 Java 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 in EnumSet

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

Iteration of EnumSet

The iterator returned by the iterator method of the EnumSet class 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 in Java 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.

Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));

That's all for this topic EnumSet in Java With Examples. 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 With Examples
  3. TreeSet in Java With Examples
  4. CopyOnWriteArraySet in Java With Examples
  5. Java Collections Interview Questions And Answers

You may also like-

  1. How to Sort ArrayList of Custom Objects in Java
  2. How and Why to Synchronize ArrayList in Java
  3. How LinkedList Class Works Internally in Java
  4. equals() And hashCode() Methods in Java
  5. Polymorphism in Java
  6. Difference Between sleep And wait in Java Multi-Threading
  7. Lambda expressions in Java 8
  8. Serialization and Deserialization in Java

No comments:

Post a Comment