Since Enum always has fixed number of instances, data-structure which is used to store Enum can be optimized depending upon number of instances
EnumSet is an abstract class and it provides two concrete implementations, java.util.RegularEnumSet and java.util.JumboEnumSet. Main difference between RegularEnumSet and JumboEnumSet is that former uses a long variable to store elements while later uses a long[] to store its element. Since RegularEnumSet uses long variable, which is a 64 bit data type, it can only hold that much of element. That's why when an empty EnumSet is created using EnumSet.noneOf() method, it choose RegularEnumSet if key universe (number of enum instances in Key Enum) is less than or equal to 64 and JumboEnumSet if key universe is more than 64.
From: EnumSet in Java - RegularEnumSet vs JumboEnumSet
RegularEnumSet
public boolean add(E e) {
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum)e).ordinal());
return elements != oldElements;
}
public boolean remove(Object e) {
if (e == null)
return false;
Class eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
long oldElements = elements;
elements &= ~(1L << ((Enum)e).ordinal());
return elements != oldElements;
}
JumboEnumSet
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> {
Read full article from Difference between RegularEnumSet and JumboEnumSet in Java | Java67
How EnumSet is implemented in Java
From: EnumSet in Java - RegularEnumSet vs JumboEnumSet
- EnumSet can only be created of a single enum type, which means you can not create EnumSet of Month and DayOfWeek together.
- EnumSet doesn't allow null elements. Attempting to insert null on EnumSet will throwNullPointerException.
- EnumSet is not thread-safe, which means if it needs to be externally synchronized, when multiple threads access it and one of them modifies the collection.
- Iterator of EnumSet is fail-safe and weakly consistent, which means noConcurrentModificationException. Also traversing order of Iterator is defined by natural ordering of Enum, and it may or may not show result of any modification done during iteration.
- EnumSet is a high performance Java Collection. It provides O(1) performance for add(),contains() and next() operations because of array based access. Preferably, useEnumSet over HashSet for storing Enum constants.
RegularEnumSet
public boolean add(E e) {
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum)e).ordinal());
return elements != oldElements;
}
public boolean remove(Object e) {
if (e == null)
return false;
Class eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
long oldElements = elements;
elements &= ~(1L << ((Enum)e).ordinal());
return elements != oldElements;
}
JumboEnumSet
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> {
/**
* Bit vector representation of this set. The ith bit of the jth
* element of this array represents the presence of universe[64*j +i]
* in this set.
*/
private long elements[];
public boolean add(E e) {
typeCheck(e);
int eOrdinal = e.ordinal();
int eWordNum = eOrdinal >>> 6;
long oldElements = elements[eWordNum];
elements[eWordNum] |= (1L << eOrdinal);
boolean result = (elements[eWordNum] != oldElements);
if (result)
size++;
return result;
}
public boolean remove(Object e) {
if (e == null)
return false;
Class eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
int eOrdinal = ((Enum)e).ordinal();
int eWordNum = eOrdinal >>> 6;
long oldElements = elements[eWordNum];
elements[eWordNum] &= ~(1L << eOrdinal);
boolean result = (elements[eWordNum] != oldElements);
if (result)
size--;
return result;
}
No comments:
Post a Comment