KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > collection > WeakSet


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util.collection;
23
24 import java.lang.ref.ReferenceQueue JavaDoc;
25
26 import java.util.Set JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.AbstractSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.NoSuchElementException JavaDoc;
31
32 import org.jboss.util.NullArgumentException;
33 import org.jboss.util.WeakObject;
34
35 /**
36  * A <tt>Set</tt> implementation with <em>weak elements</em>. An entry in
37  * a <tt>WeakSet</tt> will automatically be removed when the element is no
38  * longer in ordinary use. More precisely, the presence of an given element
39  * will not prevent the element from being discarded by the garbage collector,
40  * that is, made finalizable, finalized, and then reclaimed.
41  *
42  * @version <tt>$Revision: 1958 $</tt>
43  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
44  */

45 public class WeakSet
46    extends AbstractSet JavaDoc
47    implements Set JavaDoc
48 {
49    /** The reference queue used to get object removal notifications. */
50    protected final ReferenceQueue JavaDoc queue = new ReferenceQueue JavaDoc();
51
52    /** The <tt>Set</tt> which will be used for element storage. */
53    protected final Set JavaDoc set;
54
55    /**
56     * Construct a <tt>WeakSet</tt>. Any elements in the given set will be
57     * wrapped in {@link WeakObject} references.
58     *
59     * @param set The <tt>Set</tt> which will be used for element storage.
60     *
61     * @throws NullArgumentException Set is <tt>null</tt>.
62     */

63    public WeakSet(final Set JavaDoc set) {
64       if (set == null)
65          throw new NullArgumentException("set");
66
67       // reset any elements to weak objects
68
if (set.size() != 0) {
69          Object JavaDoc elements[] = set.toArray();
70          set.clear();
71
72          for (int i=0; i<elements.length; i++) {
73             add(elements[i]);
74          }
75       }
76
77       this.set = set;
78    }
79
80    /**
81     * Construct a <tt>WeakSet</tt> based on a <tt>HashSet</tt>.
82     */

83    public WeakSet() {
84       this(new HashSet JavaDoc());
85    }
86
87    /**
88     * Maintain the elements in the set. Removes objects from the set that
89     * have been reclaimed due to GC.
90     */

91    protected final void maintain() {
92       WeakObject weak;
93       while ((weak = (WeakObject)queue.poll()) != null) {
94          set.remove(weak);
95       }
96    }
97
98    /**
99     * Return the size of the set.
100     *
101     * @return The size of the set.
102     */

103    public int size() {
104       maintain();
105
106       return set.size();
107    }
108
109    /**
110     * Return an iteration over the elements in the set.
111     *
112     * @return An iteration over the elements in the set.
113     */

114    public Iterator JavaDoc iterator() {
115       return new Iterator JavaDoc() {
116
117             /** The set's iterator */
118             Iterator JavaDoc iter = set.iterator();
119
120             /** The next available object. */
121             Object JavaDoc next = null;
122
123             public boolean hasNext() {
124                while (iter.hasNext()) {
125                   WeakObject weak = (WeakObject)iter.next();
126                   Object JavaDoc obj = null;
127                   if (weak != null && (obj = weak.get()) == null) {
128                      // object has been reclaimed by the GC
129
continue;
130                   }
131
132                   next = obj;
133                   return true;
134                }
135
136                return false;
137             }
138
139             public Object JavaDoc next() {
140                if ((next == null) && !hasNext()) {
141                   throw new NoSuchElementException JavaDoc();
142                }
143
144                Object JavaDoc obj = next;
145                next = null;
146
147                return obj;
148             }
149
150             public void remove() {
151                iter.remove();
152             }
153          };
154    }
155
156    /**
157     * Add an element to the set.
158     *
159     * @param obj Element to add to the set.
160     * @return True if the element was added.
161     */

162    public boolean add(final Object JavaDoc obj) {
163       maintain();
164
165       return set.add(WeakObject.create(obj, queue));
166    }
167
168    /**
169     * Returns <tt>true</tt> if this set contains no elements.
170     *
171     * @return <tt>true</tt> if this set contains no elements.
172     */

173    public boolean isEmpty() {
174       maintain();
175
176       return set.isEmpty();
177    }
178
179    /**
180     * Returns <tt>true</tt> if this set contains the specified element.
181     *
182     * @param obj Element whose presence in this set is to be tested.
183     * @return <tt>true</tt> if this set contains the specified element.
184     */

185    public boolean contains(final Object JavaDoc obj) {
186       maintain();
187
188       return set.contains(WeakObject.create(obj));
189    }
190
191    /**
192     * Removes the given element from this set if it is present.
193     *
194     * @param obj Object to be removed from this set, if present.
195     * @return <tt>true</tt> if the set contained the specified element.
196     */

197    public boolean remove(final Object JavaDoc obj) {
198       maintain();
199
200       return set.remove(WeakObject.create(obj));
201    }
202
203    /**
204     * Removes all of the elements from this set.
205     */

206    public void clear() {
207       set.clear();
208    }
209
210    /**
211      * Returns a shallow copy of this <tt>WeakSet</tt> instance: the elements
212      * themselves are not cloned.
213      *
214      * @return A shallow copy of this set.
215      */

216    public Object JavaDoc clone() {
217       maintain();
218
219       try {
220          return super.clone();
221       }
222       catch (CloneNotSupportedException JavaDoc e) {
223          throw new InternalError JavaDoc();
224       }
225    }
226 }
227
Popular Tags