All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.molindo.utils.collections.IdentityHashSet Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/**
 * Copyright 2010 Molindo GmbH
 *
 * Licensed 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.
 */

package at.molindo.utils.collections;

import java.util.AbstractSet;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Set;

public class IdentityHashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable {
	static final long serialVersionUID = -5024744406713321676L;

	private transient IdentityHashMap map;

	// Dummy value to associate with an Object in the backing Map
	private static final Object PRESENT = new Object();

	public IdentityHashSet() {
		map = new IdentityHashMap();
	}

	public IdentityHashSet(Collection c) {
		map = new IdentityHashMap(Math.max((int) (c.size() / .75f) + 1, 16));
		addAll(c);
	}

	public IdentityHashSet(int expectedMaxSize) {
		map = new IdentityHashMap(expectedMaxSize);
	}

	/**
	 * Returns an iterator over the elements in this set. The elements are
	 * returned in no particular order.
	 * 
	 * @return an Iterator over the elements in this set
	 * @see ConcurrentModificationException
	 */
	@Override
	public Iterator iterator() {
		return map.keySet().iterator();
	}

	/**
	 * Returns the number of elements in this set (its cardinality).
	 * 
	 * @return the number of elements in this set (its cardinality)
	 */
	@Override
	public int size() {
		return map.size();
	}

	/**
	 * Returns true if this set contains no elements.
	 * 
	 * @return true if this set contains no elements
	 */
	@Override
	public boolean isEmpty() {
		return map.isEmpty();
	}

	/**
	 * Returns true if this set contains the specified element. More
	 * formally, returns true if and only if this set contains an
	 * element e such that
	 * (o==null ? e==null : o.equals(e)).
	 * 
	 * @param o
	 *            element whose presence in this set is to be tested
	 * @return true if this set contains the specified element
	 */
	@Override
	public boolean contains(Object o) {
		return map.containsKey(o);
	}

	/**
	 * Adds the specified element to this set if it is not already present. More
	 * formally, adds the specified element e to this set if this set
	 * contains no element e2 such that
	 * (e==null ? e2==null : e.equals(e2)). If this
	 * set already contains the element, the call leaves the set unchanged and
	 * returns false.
	 * 
	 * @param e
	 *            element to be added to this set
	 * @return true if this set did not already contain the specified
	 *         element
	 */
	@Override
	public boolean add(E e) {
		return map.put(e, PRESENT) == null;
	}

	/**
	 * Removes the specified element from this set if it is present. More
	 * formally, removes an element e such that
	 * (o==null ? e==null : o.equals(e)), if this
	 * set contains such an element. Returns true if this set contained
	 * the element (or equivalently, if this set changed as a result of the
	 * call). (This set will not contain the element once the call returns.)
	 * 
	 * @param o
	 *            object to be removed from this set, if present
	 * @return true if the set contained the specified element
	 */
	@Override
	public boolean remove(Object o) {
		return map.remove(o) == PRESENT;
	}

	/**
	 * Removes all of the elements from this set. The set will be empty after
	 * this call returns.
	 */
	@Override
	public void clear() {
		map.clear();
	}

	/**
	 * Returns a shallow copy of this HashSet instance: the elements
	 * themselves are not cloned.
	 * 
	 * @return a shallow copy of this set
	 */
	@Override
	@SuppressWarnings("unchecked")
	public IdentityHashSet clone() {
		try {
			IdentityHashSet newSet = (IdentityHashSet) super.clone();
			newSet.map = (IdentityHashMap) map.clone();
			return newSet;
		} catch (CloneNotSupportedException e) {
			throw new InternalError();
		}
	}

	/**
	 * Save the state of this HashSet instance to a stream (that is,
	 * serialize it).
	 * 
	 * @serialData The capacity of the backing HashMap instance (int),
	 *             and its load factor (float) are emitted, followed by the size
	 *             of the set (the number of elements it contains) (int),
	 *             followed by all of its elements (each an Object) in no
	 *             particular order.
	 */
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
		// Write out any hidden serialization magic
		s.defaultWriteObject();

		// Write out size
		s.writeInt(map.size());

		// Write out all elements in the proper order.
		for (Iterator i = map.keySet().iterator(); i.hasNext();) {
			s.writeObject(i.next());
		}
	}

	/**
	 * Reconstitute the HashSet instance from a stream (that is,
	 * deserialize it).
	 */
	@SuppressWarnings("unchecked")
	private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
		// Read in any hidden serialization magic
		s.defaultReadObject();

		// Read in size
		int size = s.readInt();

		// backing map with expected size
		map = new IdentityHashMap(size);

		// Read in all elements in the proper order.
		for (int i = 0; i < size; i++) {
			E e = (E) s.readObject();
			map.put(e, PRESENT);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy