More about Set implementations

Special-Purpose Set Implementations
There are two special-purpose Set implementations — EnumSet and CopyOnWriteArraySet.
EnumSet is a high-performance Set implementation for enum types. All of the members of an enum set must be of the same enum type. Internally, it is represented by a bit-vector, typically a single long. Enum sets support iteration over ranges of enum types. For example, given the enum declaration for the days of the week, you can iterate over the weekdays. The EnumSet class provides a static factory that makes it easy.
for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY))
System.out.println(d);
Enum sets also provide a rich, typesafe replacement for traditional bit flags.
EnumSet.of(Style.BOLD, Style.ITALIC)
CopyOnWriteArraySet is a Set implementation backed up by a copy-on-write array. All mutative operations, such as add, set, and remove, are implemented by making a new copy of the array; no locking is ever required. Even iteration may safely proceed concurrently with element insertion and deletion. Unlike most Set implementations, the add, remove, and contains methods require time proportional to the size of the set. This implementation is only appropriate for sets that are rarely modified but frequently iterated. It is well suited to maintaining event-handler lists that must prevent duplicates.
a). EnumSet: - A specialized Set implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created. 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.
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.
Null elements are not permitted. Attempts to insert a null element will throw NullPointerException. Attempts to test for the presence of a null element or to remove one will, however, function properly.
Like most collection implementations, 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. This is typically accomplished by synchronizing on some object that naturally encapsulates the enum set. If no such object exists, the set should be "wrapped" using the Collections.synchronizedSet(java.util.Set) method. This is best done at creation time, to prevent accidental unsynchronized access:
Set s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be much faster than their HashSet counterparts. Even bulk operations execute in constant time if their argument is also an enum set.
Example: -
import java.util.EnumSet;
import java.util.Set;
/**
* Simple Java Program to demonstrate how to use EnumSet.
* It has some interesting use cases and it's specialized collection for
* Enumeration types. Using Enum with EnumSet will give you far better
* performance than using Enum with HashSet, or LinkedHashSet.
*
* @author Anuj Bhargava
*/
class EnumSetDemo {
private enum Color {
RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255);
private int r;
private int g;
private int b;
private Color(int r, int g, int b) {
this.r = r;
this.g = g;
this.b = b;
}
public int getR() {
return r;
}
public int getG() {
return g;
}
public int getB() {
return b;
}
}
public static void main(String args[]) {
// this will draw line in yellow color
EnumSet yellow = EnumSet.of(Color.RED, Color.GREEN);
drawLine(yellow);
// RED + GREEN + BLUE = WHITE
EnumSet white = EnumSet.of(Color.RED, Color.GREEN, Color.BLUE);
drawLine(white);
// RED + BLUE = PINK
EnumSet pink = EnumSet.of(Color.RED, Color.BLUE);
drawLine(pink);
}
public static void drawLine(Set colors) {
System.out.println("Requested Colors to draw lines : " + colors);
for (Color c : colors) {
System.out.println("drawing line in color : " + c);
}
}
}
Output: -
C:\java\word>javac EnumSetDemo.java
C:\java\word>java EnumSetDemo
Requested Colors to draw lines : [RED, GREEN]
drawing line in color : RED
drawing line in color : GREEN
Requested Colors to draw lines : [RED, GREEN, BLUE]
drawing line in color : RED
drawing line in color : GREEN
drawing line in color : BLUE
Requested Colors to draw lines : [RED, BLUE]
drawing line in color : RED
drawing line in color : BLUE
b).CopyOnWriteArraySet: - A Set that uses an internal CopyOnWriteArrayList for all of its operations. Thus, it shares the same basic properties:
* It is best suited for applications in which set sizes generally stay small, read-only operations vastly outnumber mutative operations, and you need to prevent interference among threads during traversal.
* It is thread-safe.
* Mutative operations (add, set, remove, etc.) are expensive since they usually entail copying the entire underlying array. * Iterators do not support the mutative remove operation.
* Traversal via iterators is fast and cannot encounter interference from other threads. Iterators rely on unchanging snapshots of the array at the time the iterators were constructed.
Example: -
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
* Java program to demonstrate What is CopyOnWriteArrayList in Java,
* Iterator of CopyOnWriteArrayList
* doesn’t support add, remove or any modification operation.
*
* @author Anuj Bhargava
*/
class CopyOnWriteArrayListExample{
public static void main(String args[]) {
CopyOnWriteArrayList threadSafeList = new CopyOnWriteArrayList();
threadSafeList.add("Java");
threadSafeList.add("J2EE");
threadSafeList.add("Collection");
//add, remove operator is not supported by CopyOnWriteArrayList iterator
Iterator failSafeIterator = threadSafeList.iterator();
while(failSafeIterator.hasNext()){
System.out.printf("Read from CopyOnWriteArrayList : %s %n", failSafeIterator.next());
failSafeIterator.remove(); //not supported in CopyOnWriteArrayList in Java
}
}
}
Output: -
C:\java\word>javac CopyOnWriteArrayListExample.java
C:\java\word>java CopyOnWriteArrayListExample
Read from CopyOnWriteArrayList : Java
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(Unknown Source) at CopyOnWriteArrayListExample.main(MyListTest1.java:25)


Free Web Hosting