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 java.lang.Boolean.TRUE;
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.Set;
23  import java.util.WeakHashMap;
24  
25  /**
26   * @author Sebastian Thomschke
27   */
28  public final class WeakHashSet<E> implements Set<E>, Serializable
29  {
30  	private static final long serialVersionUID = 1L;
31  
32  	private transient WeakHashMap<E, Object> map;
33  
34  	/**
35  	 * Constructs a new, empty <tt>WeakHashSet</tt>; the backing <tt>WeakHashMap</tt> instance has
36  	 * default initial capacity (16) and load factor (0.75).
37  	 */
38  	public WeakHashSet()
39  	{
40  		map = new WeakHashMap<E, Object>();
41  	}
42  
43  	/**
44  	 * Constructs a new, empty <tt>WeakHashSet</tt>; the backing <tt>WeakHashMap</tt> instance has
45  	 * the given initial capacity and the default load factor (0.75).
46  	 */
47  	public WeakHashSet(final int initialCapacity)
48  	{
49  		map = new WeakHashMap<E, Object>(initialCapacity);
50  	}
51  
52  	/**
53  	 * {@inheritDoc}
54  	 */
55  	public boolean add(final E o)
56  	{
57  		return map.put(o, TRUE) == null;
58  	}
59  
60  	/**
61  	 * {@inheritDoc}
62  	 */
63  	public boolean addAll(final Collection< ? extends E> c)
64  	{
65  		int count = 0;
66  		for (final E e : c)
67  			if (add(e)) count++;
68  		return count > 0;
69  	}
70  
71  	public void clear()
72  	{
73  		map.clear();
74  	}
75  
76  	/**
77  	 * {@inheritDoc}
78  	 */
79  	public boolean contains(final Object o)
80  	{
81  		return map.containsKey(o);
82  	}
83  
84  	/**
85  	 * {@inheritDoc}
86  	 */
87  	public boolean containsAll(final Collection< ? > c)
88  	{
89  		return map.keySet().containsAll(c);
90  	}
91  
92  	/**
93  	 * {@inheritDoc}
94  	 */
95  	@Override
96  	public boolean equals(final Object o)
97  	{
98  		if (o == this) return true;
99  
100 		if (!(o instanceof Set< ? >)) return false;
101 
102 		final Set< ? > set = (Set< ? >) o;
103 
104 		if (set.size() != size()) return false;
105 
106 		return containsAll(set);
107 	}
108 
109 	/**
110 	 * {@inheritDoc}
111 	 */
112 	@Override
113 	public int hashCode()
114 	{
115 		int hash = 0;
116 		for (final E e : map.keySet())
117 			if (e != null) hash += e.hashCode();
118 		return hash;
119 	}
120 
121 	/**
122 	 * {@inheritDoc}
123 	 */
124 	public boolean isEmpty()
125 	{
126 		return map.isEmpty();
127 	}
128 
129 	/**
130 	 * {@inheritDoc}
131 	 */
132 	public Iterator<E> iterator()
133 	{
134 		return map.keySet().iterator();
135 	}
136 
137 	/**
138 	 * Reads the <tt>WeakHashSet</tt> instance from a stream.
139 	 */
140 	@SuppressWarnings("unchecked")
141 	private void readObject(final ObjectInputStream ois) throws java.io.IOException, ClassNotFoundException
142 	{
143 		// materialize any hidden serialization magic
144 		ois.defaultReadObject();
145 
146 		// materialize the size
147 		final int size = ois.readInt();
148 
149 		// materialize the elements
150 		map = new WeakHashMap<E, Object>(size);
151 		for (int i = 0; i < size; i++)
152 			map.put((E) ois.readObject(), TRUE);
153 	}
154 
155 	/**
156 	 * {@inheritDoc}
157 	 */
158 	public boolean remove(final Object o)
159 	{
160 		return map.remove(o) == TRUE;
161 	}
162 
163 	/**
164 	 * {@inheritDoc}
165 	 */
166 	public boolean removeAll(final Collection< ? > c)
167 	{
168 		return map.keySet().removeAll(c);
169 	}
170 
171 	/**
172 	 * {@inheritDoc}
173 	 */
174 	public boolean retainAll(final Collection< ? > c)
175 	{
176 		return map.keySet().retainAll(c);
177 	}
178 
179 	/**
180 	 * {@inheritDoc}
181 	 */
182 	public int size()
183 	{
184 		return map.size();
185 	}
186 
187 	/**
188 	 * {@inheritDoc}
189 	 */
190 	public Object[] toArray()
191 	{
192 		return map.keySet().toArray();
193 	}
194 
195 	/**
196 	 * {@inheritDoc}
197 	 */
198 	public <T> T[] toArray(final T[] a)
199 	{
200 		return map.keySet().toArray(a);
201 	}
202 
203 	/**
204 	 * Writes the state of this <tt>WeakHashSet</tt> instance to a stream.
205 	 */
206 	private void writeObject(final ObjectOutputStream oos) throws java.io.IOException
207 	{
208 		// serialize any hidden serialization magic
209 		oos.defaultWriteObject();
210 
211 		// serialize the set's size
212 		oos.writeInt(map.size());
213 
214 		// serialize the set's elements
215 		for (final E e : map.keySet())
216 			oos.writeObject(e);
217 	}
218 }