View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
3    * Thomschke.
4    * 
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    * 
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.internal.util;
14  
15  import static net.sf.oval.Validator.getCollectionFactory;
16  
17  import java.io.ObjectInputStream;
18  import java.io.ObjectOutputStream;
19  import java.io.Serializable;
20  import java.util.Collection;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.Set;
24  
25  /**
26   * @author Sebastian Thomschke
27   */
28  public final class IdentitySet<E> implements Set<E>, Serializable
29  {
30  	private static final long serialVersionUID = 1L;
31  
32  	private transient Map<Integer, E> map;
33  
34  	/**
35  	 * Constructs a new, empty <tt>IdentitySet</tt>; the backing <tt>Map</tt> instance has
36  	 * default initial capacity (16) and load factor (0.75).
37  	 */
38  	public IdentitySet()
39  	{
40  		map = getCollectionFactory().createMap();
41  	}
42  
43  	/**
44  	 * Constructs a new, empty <tt>IdentitySet</tt>; the backing <tt>Map</tt> instance has
45  	 * the given initial capacity and the default load factor (0.75).
46  	 */
47  	public IdentitySet(final int initialCapacity)
48  	{
49  		map = getCollectionFactory().createMap(initialCapacity);
50  	}
51  
52  	/**
53  	 * {@inheritDoc}
54  	 */
55  	public boolean add(final E o)
56  	{
57  		final int hash = System.identityHashCode(o);
58  		return map.put(hash, o) == null;
59  	}
60  
61  	/**
62  	 * {@inheritDoc}
63  	 */
64  	public boolean addAll(final Collection< ? extends E> c)
65  	{
66  		int count = 0;
67  		for (final E e : c)
68  			if (add(e)) count++;
69  		return count > 0;
70  	}
71  
72  	/**
73  	 * {@inheritDoc}
74  	 */
75  	public void clear()
76  	{
77  		map.clear();
78  	}
79  
80  	/**
81  	 * {@inheritDoc}
82  	 */
83  	public boolean contains(final Object o)
84  	{
85  		final int hash = System.identityHashCode(o);
86  		return map.containsKey(hash);
87  	}
88  
89  	/**
90  	 * {@inheritDoc}
91  	 */
92  	public boolean containsAll(final Collection< ? > c)
93  	{
94  		throw new UnsupportedOperationException();
95  	}
96  
97  	/**
98  	 * {@inheritDoc}
99  	 */
100 	public boolean isEmpty()
101 	{
102 		return map.isEmpty();
103 	}
104 
105 	/**
106 	 * {@inheritDoc}
107 	 */
108 	public Iterator<E> iterator()
109 	{
110 		return map.values().iterator();
111 	}
112 
113 	/**
114 	 * Reads the <tt>IdentitySet</tt> instance from a stream.
115 	 */
116 	@SuppressWarnings("unchecked")
117 	private void readObject(final ObjectInputStream ois) throws java.io.IOException, ClassNotFoundException
118 	{
119 		// materialize any hidden serialization magic
120 		ois.defaultReadObject();
121 
122 		// materialize the size
123 		final int size = ois.readInt();
124 
125 		// materialize the elements
126 		map = getCollectionFactory().createMap(size);
127 		for (int i = 0; i < size; i++)
128 		{
129 			final E o = (E) ois.readObject();
130 			final int hash = System.identityHashCode(o);
131 			map.put(hash, o);
132 		}
133 	}
134 
135 	/**
136 	 * {@inheritDoc}
137 	 */
138 	public boolean remove(final Object o)
139 	{
140 		final int hash = System.identityHashCode(o);
141 		return map.remove(hash) != null;
142 	}
143 
144 	/**
145 	 * {@inheritDoc}
146 	 */
147 	public boolean removeAll(final Collection< ? > c)
148 	{
149 		boolean modified = false;
150 		for (final Object e : c)
151 			if (remove(e)) modified = true;
152 		return modified;
153 	}
154 
155 	/**
156 	 * {@inheritDoc}
157 	 */
158 	public boolean retainAll(final Collection< ? > c)
159 	{
160 		throw new UnsupportedOperationException();
161 	}
162 
163 	/**
164 	 * {@inheritDoc}
165 	 */
166 	public int size()
167 	{
168 		return map.size();
169 	}
170 
171 	/**
172 	 * {@inheritDoc}
173 	 */
174 	public Object[] toArray()
175 	{
176 		return map.values().toArray();
177 	}
178 
179 	/**
180 	 * {@inheritDoc}
181 	 */
182 	public <T> T[] toArray(final T[] a)
183 	{
184 		return map.values().toArray(a);
185 	}
186 
187 	/**
188 	 * Writes state of this <tt>IdentitySet</tt> instance to a stream.
189 	 */
190 	private void writeObject(final ObjectOutputStream oos) throws java.io.IOException
191 	{
192 		// serialize any hidden serialization magic
193 		oos.defaultWriteObject();
194 
195 		// serialize the set's size
196 		oos.writeInt(map.size());
197 
198 		// serialize the set's elements
199 		for (final E e : map.values())
200 			oos.writeObject(e);
201 	}
202 }