Collections Data Structure Java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
 * This class implements the Set interface, backed by a ConcurrentHashMap instance.
 * 
 * @author Matt Tucker
 * @param 
 */
public class ConcurrentHashSet extends AbstractSet
  implements
    Set,
    Cloneable,
    java.io.Serializable
{
  /** */
  private static final long serialVersionUID = 1L;
  private transient ConcurrentHashMap map;
  // Dummy value to associate with an Object in the backing Map
  private static final Object PRESENT = new Object();
  /**
   * Constructs a new, empty set; the backing ConcurrentHashMap instance has default
   * initial capacity (16) and load factor (0.75).
   */
  public ConcurrentHashSet()
  {
    map = new ConcurrentHashMap();
  }
  /**
   * Constructs a new set containing the elements in the specified collection. The
   * ConcurrentHashMap is created with default load factor (0.75) and an initial capacity
   * sufficient to contain the elements in the specified collection.
   * 
   * @param c
   *            the collection whose elements are to be placed into this set.
   * @throws NullPointerException
   *             if the specified collection is null.
   */
  public ConcurrentHashSet(Collection c)
  {
    map = new ConcurrentHashMap(Math.max((int)(c.size() / .75f) + 1, 16));
    addAll(c);
  }
  /**
   * Constructs a new, empty set; the backing ConcurrentHashMap instance has the
   * specified initial capacity and the specified load factor.
   * 
   * @param initialCapacity
   *            the initial capacity of the hash map.
   * @param loadFactor
   *            the load factor of the hash map.
   * @throws IllegalArgumentException
   *             if the initial capacity is less than zero, or if the load factor is nonpositive.
   */
  public ConcurrentHashSet(int initialCapacity, float loadFactor)
  {
    map = new ConcurrentHashMap(initialCapacity, loadFactor, 16);
  }
  /**
   * Constructs a new, empty set; the backing HashMap instance has the specified initial
   * capacity and default load factor, which is 0.75.
   * 
   * @param initialCapacity
   *            the initial capacity of the hash table.
   * @throws IllegalArgumentException
   *             if the initial capacity is less than zero.
   */
  public ConcurrentHashSet(int initialCapacity)
  {
    map = new ConcurrentHashMap(initialCapacity);
  }
  /**
   * 
   * @see java.util.AbstractCollection#iterator()
   */
  @Override
  public Iterator iterator()
  {
    return map.keySet().iterator();
  }
  /**
   * 
   * @see java.util.AbstractCollection#size()
   */
  @Override
  public int size()
  {
    return map.size();
  }
  /**
   * 
   * @see java.util.AbstractCollection#isEmpty()
   */
  @Override
  public boolean isEmpty()
  {
    return map.isEmpty();
  }
  /**
   * 
   * @see java.util.AbstractCollection#contains(java.lang.Object)
   */
  @Override
  public boolean contains(Object o)
  {
    return map.containsKey(o);
  }
  /**
   * 
   * @see java.util.AbstractCollection#add(java.lang.Object)
   */
  @Override
  public boolean add(E o)
  {
    return map.put(o, PRESENT) == null;
  }
  /**
   * 
   * @see java.util.AbstractCollection#remove(java.lang.Object)
   */
  @Override
  public boolean remove(Object o)
  {
    return map.remove(o) == PRESENT;
  }
  /**
   * 
   * @see java.util.AbstractCollection#clear()
   */
  @Override
  public void clear()
  {
    map.clear();
  }
  /**
   * 
   * @see java.lang.Object#clone()
   */
  @SuppressWarnings("unchecked")
  @Override
  public Object clone()
  {
    try
    {
      ConcurrentHashSet newSet = (ConcurrentHashSet)super.clone();
      newSet.map.putAll(map);
      return newSet;
    }
    catch (CloneNotSupportedException e)
    {
      throw new InternalError();
    }
  }
  /**
   * 
   * @param s
   * @throws java.io.IOException
   */
  private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException
  {
    s.defaultWriteObject();
    s.writeInt(map.size());
    for (Iterator i = map.keySet().iterator(); i.hasNext();)
    {
      s.writeObject(i.next());
    }
  }
  /**
   * Re-constitute the HashSet instance from a stream.
   * 
   * @param inputStream
   * @throws ClassNotFoundException
   * @throws IOException
   */
  private void readObject(ObjectInputStream inputStream) throws ClassNotFoundException,
    IOException
  {
    inputStream.defaultReadObject();
    map = new ConcurrentHashMap();
    int size = inputStream.readInt();
    for (int i = 0; i < size; i++)
    {
      E e = (E)inputStream.readObject();
      map.put(e, PRESENT);
    }
  }
}