ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeSet.java
Revision: 1.11
Committed: Mon May 16 08:13:36 2005 UTC (19 years ago) by jsr166
Branch: MAIN
Changes since 1.10: +161 -329 lines
Log Message:
doc fixes

File Contents

# User Rev Content
1 dl 1.1 /*
2     * %W% %E%
3     *
4 jsr166 1.6 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5 dl 1.1 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6     */
7    
8 jsr166 1.8 package java.util;
9 dl 1.1
10     /**
11 jsr166 1.11 * A {@link NavigableSet} implementation based on a {@link TreeMap}.
12     * The elements are ordered using their {@linkplain Comparable natural
13     * ordering}, or by a {@link Comparator} provided at set creation
14     * time, depending on which constructor is used.
15 dl 1.1 *
16 jsr166 1.11 * <p>This implementation provides guaranteed log(n) time cost for the basic
17     * operations (<tt>add</tt>, <tt>remove</tt> and <tt>contains</tt>).
18 dl 1.1 *
19 jsr166 1.11 * <p>Note that the ordering maintained by a set (whether or not an explicit
20 dl 1.1 * comparator is provided) must be <i>consistent with equals</i> if it is to
21     * correctly implement the <tt>Set</tt> interface. (See <tt>Comparable</tt>
22     * or <tt>Comparator</tt> for a precise definition of <i>consistent with
23     * equals</i>.) This is so because the <tt>Set</tt> interface is defined in
24     * terms of the <tt>equals</tt> operation, but a <tt>TreeSet</tt> instance
25 jsr166 1.11 * performs all element comparisons using its <tt>compareTo</tt> (or
26     * <tt>compare</tt>) method, so two elements that are deemed equal by this method
27 dl 1.1 * are, from the standpoint of the set, equal. The behavior of a set
28     * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
29 jsr166 1.11 * just fails to obey the general contract of the <tt>Set</tt> interface.
30 dl 1.1 *
31 jsr166 1.11 * <p><b>Note that this implementation is not synchronized.</b> If multiple
32 dl 1.1 * threads access a set concurrently, and at least one of the threads modifies
33     * the set, it <i>must</i> be synchronized externally. This is typically
34     * accomplished by synchronizing on some object that naturally encapsulates
35     * the set. If no such object exists, the set should be "wrapped" using the
36     * <tt>Collections.synchronizedSet</tt> method. This is best done at creation
37     * time, to prevent accidental unsynchronized access to the set: <pre>
38     * SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
39 jsr166 1.11 * </pre>
40 dl 1.1 *
41 jsr166 1.11 * <p>The iterators returned by this class's <tt>iterator</tt> method are
42 dl 1.1 * <i>fail-fast</i>: if the set is modified at any time after the iterator is
43     * created, in any way except through the iterator's own <tt>remove</tt>
44 jsr166 1.11 * method, the iterator will throw a {@link ConcurrentModificationException}.
45 dl 1.1 * Thus, in the face of concurrent modification, the iterator fails quickly
46     * and cleanly, rather than risking arbitrary, non-deterministic behavior at
47     * an undetermined time in the future.
48     *
49     * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
50     * as it is, generally speaking, impossible to make any hard guarantees in the
51     * presence of unsynchronized concurrent modification. Fail-fast iterators
52     * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
53     * Therefore, it would be wrong to write a program that depended on this
54     * exception for its correctness: <i>the fail-fast behavior of iterators
55 jsr166 1.10 * should be used only to detect bugs.</i>
56 dl 1.1 *
57 jsr166 1.10 * <p>This class is a member of the
58 dl 1.1 * <a href="{@docRoot}/../guide/collections/index.html">
59     * Java Collections Framework</a>.
60     *
61 jsr166 1.11 * @param <E> the type of elements maintained by this set
62     *
63 dl 1.1 * @author Josh Bloch
64     * @version %I%, %G%
65     * @see Collection
66     * @see Set
67     * @see HashSet
68     * @see Comparable
69     * @see Comparator
70     * @see Collections#synchronizedSortedSet(SortedSet)
71     * @see TreeMap
72     * @since 1.2
73     */
74    
75     public class TreeSet<E>
76     extends AbstractSet<E>
77     implements NavigableSet<E>, Cloneable, java.io.Serializable
78     {
79     private transient NavigableMap<E,Object> m; // The backing Map
80    
81     // Dummy value to associate with an Object in the backing Map
82     private static final Object PRESENT = new Object();
83    
84     /**
85 jsr166 1.11 * Constructs a set backed by the specified navigable map.
86 dl 1.1 */
87     private TreeSet(NavigableMap<E,Object> m) {
88     this.m = m;
89     }
90    
91     /**
92 jsr166 1.11 * Constructs a new, empty tree set, sorted according to the
93     * natural ordering of its elements. All elements inserted into
94     * the set must implement the {@link Comparable} interface.
95     * Furthermore, all such elements must be <i>mutually
96     * comparable</i>: <tt>e1.compareTo(e2)</tt> must not throw a
97 dl 1.1 * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
98 jsr166 1.11 * <tt>e2</tt> in the set. If the user attempts to add an element
99     * to the set that violates this constraint (for example, the user
100     * attempts to add a string element to a set whose elements are
101     * integers), the <tt>add(Object)</tt> call will throw a
102     * <tt>ClassCastException</tt>.
103 dl 1.1 */
104     public TreeSet() {
105     this(new TreeMap<E,Object>());
106     }
107    
108     /**
109 jsr166 1.11 * Constructs a new, empty tree set, sorted according to the
110     * specified comparator. All elements inserted into the set must
111     * be <i>mutually comparable</i> by the specified comparator:
112     * <tt>comparator.compare(e1, e2)</tt> must not throw a
113     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
114     * <tt>e2</tt> in the set. If the user attempts to add an element
115     * to the set that violates this constraint, the
116     * <tt>add(Object)</tt> call will throw a
117     * <tt>ClassCastException</tt>.
118     *
119     * @param comparator the comparator that will be used to order this set.
120     * If <tt>null</tt>, the {@linkplain Comparable natural
121     * ordering} of the elements will be used.
122     */
123     public TreeSet(Comparator<? super E> comparator) {
124     this(new TreeMap<E,Object>(comparator));
125 dl 1.1 }
126    
127     /**
128 jsr166 1.11 * Constructs a new tree set containing the elements in the
129     * specified collection, sorted according to the <i>natural
130     * ordering</i> of its elements. All elements inserted into the
131     * set must implement the {@link Comparable} interface.
132     * Furthermore, all such elements must be <i>mutually
133     * comparable</i>: <tt>e1.compareTo(e2)</tt> must not throw a
134     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
135     * <tt>e2</tt> in the set.
136     *
137     * @param c collection whose elements will comprise the new set
138     * @throws ClassCastException if the elements in <tt>c</tt> are
139     * not {@link Comparable}, or are not mutually comparable
140     * @throws NullPointerException if the specified collection is null
141 dl 1.1 */
142     public TreeSet(Collection<? extends E> c) {
143     this();
144     addAll(c);
145     }
146    
147     /**
148 jsr166 1.11 * Constructs a new tree set containing the same elements and
149     * using the same ordering as the specified sorted set.
150 dl 1.1 *
151 jsr166 1.11 * @param s sorted set whose elements will comprise the new set
152     * @throws NullPointerException if the specified sorted set is null
153 dl 1.1 */
154     public TreeSet(SortedSet<E> s) {
155     this(s.comparator());
156     addAll(s);
157     }
158    
159     /**
160     * Returns an iterator over the elements in this set. The elements
161     * are returned in ascending order.
162     *
163 jsr166 1.11 * @return an iterator over the elements in this set
164 dl 1.1 */
165     public Iterator<E> iterator() {
166 jsr166 1.11 return m.keySet().iterator();
167 dl 1.1 }
168    
169     /**
170     * Returns an iterator over the elements in this set. The elements
171     * are returned in descending order.
172     *
173 jsr166 1.11 * @return an iterator over the elements in this set
174 dl 1.1 */
175     public Iterator<E> descendingIterator() {
176     return m.descendingKeySet().iterator();
177     }
178    
179     /**
180     * Returns the number of elements in this set (its cardinality).
181     *
182 jsr166 1.11 * @return the number of elements in this set (its cardinality)
183 dl 1.1 */
184     public int size() {
185     return m.size();
186     }
187    
188     /**
189     * Returns <tt>true</tt> if this set contains no elements.
190     *
191 jsr166 1.11 * @return <tt>true</tt> if this set contains no elements
192 dl 1.1 */
193     public boolean isEmpty() {
194     return m.isEmpty();
195     }
196    
197     /**
198     * Returns <tt>true</tt> if this set contains the specified element.
199     *
200 jsr166 1.11 * @param o the object to be checked for containment in this set
201     * @return <tt>true</tt> if this set contains the specified element
202 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
203 jsr166 1.11 * with the elements currently in the set
204     * @throws NullPointerException if the specified element is null and
205     * this set uses natural ordering and is non-empty, or its
206     * comparator does not permit null elements
207 dl 1.1 */
208     public boolean contains(Object o) {
209     return m.containsKey(o);
210     }
211    
212     /**
213     * Adds the specified element to this set if it is not already present.
214     *
215 jsr166 1.11 * @param e element to be added to this set
216 dl 1.1 * @return <tt>true</tt> if the set did not already contain the specified
217 jsr166 1.11 * element
218 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
219 jsr166 1.11 * with the elements currently in the set
220     * @throws NullPointerException if the specified element is null and
221     * this set uses natural ordering and is non-empty, or its
222     * comparator does not permit null elements
223 dl 1.1 */
224 jsr166 1.7 public boolean add(E e) {
225     return m.put(e, PRESENT)==null;
226 dl 1.1 }
227    
228     /**
229     * Removes the specified element from this set if it is present.
230     *
231 jsr166 1.11 * @param o object to be removed from this set, if present
232     * @return <tt>true</tt> if the set contained the specified element
233 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
234 jsr166 1.11 * with the elements currently in the set
235     * @throws NullPointerException if the specified element is null and
236     * this set uses natural ordering and is non-empty, or its
237     * comparator does not permit null elements
238 dl 1.1 */
239     public boolean remove(Object o) {
240     return m.remove(o)==PRESENT;
241     }
242    
243     /**
244     * Removes all of the elements from this set.
245 jsr166 1.11 * The set will be empty after this call returns.
246 dl 1.1 */
247     public void clear() {
248     m.clear();
249     }
250    
251     /**
252     * Adds all of the elements in the specified collection to this set.
253     *
254     * @param c elements to be added
255 jsr166 1.11 * @return <tt>true</tt> if this set changed as a result of the call
256 dl 1.1 * @throws ClassCastException if the elements provided cannot be compared
257 jsr166 1.11 * with the elements currently in the set
258     * @throws NullPointerException if the specified collection is null or
259     * if any element is null and this set uses natural ordering, or
260     * its comparator does not permit null elements
261 dl 1.1 */
262     public boolean addAll(Collection<? extends E> c) {
263     // Use linear-time version if applicable
264     if (m.size()==0 && c.size() > 0 &&
265     c instanceof SortedSet &&
266     m instanceof TreeMap) {
267 jsr166 1.9 SortedSet<? extends E> set = (SortedSet<? extends E>) c;
268 dl 1.1 TreeMap<E,Object> map = (TreeMap<E, Object>) m;
269 jsr166 1.9 Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
270 dl 1.1 Comparator<? super E> mc = map.comparator();
271     if (cc==mc || (cc != null && cc.equals(mc))) {
272     map.addAllForTreeSet(set, PRESENT);
273     return true;
274     }
275     }
276     return super.addAll(c);
277     }
278    
279     /**
280 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
281 dl 1.1 * @throws NullPointerException if <tt>fromElement</tt> or
282 jsr166 1.11 * <tt>toElement</tt> is null and this set uses natural ordering,
283     * or its comparator does not permit null elements
284     * @throws IllegalArgumentException {@inheritDoc}
285 dl 1.1 */
286 dl 1.3 public NavigableSet<E> navigableSubSet(E fromElement, E toElement) {
287     return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
288 dl 1.1 }
289    
290     /**
291 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
292     * @throws NullPointerException if <tt>toElement</tt> is null and
293     * this set uses natural ordering, or its comparator does
294     * not permit null elements
295     * @throws IllegalArgumentException {@inheritDoc}
296 dl 1.1 */
297 dl 1.3 public NavigableSet<E> navigableHeadSet(E toElement) {
298     return new TreeSet<E>(m.navigableHeadMap(toElement));
299 dl 1.1 }
300    
301     /**
302 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
303     * @throws NullPointerException if <tt>fromElement</tt> is null and
304     * this set uses natural ordering, or its comparator does
305     * not permit null elements
306     * @throws IllegalArgumentException {@inheritDoc}
307 dl 1.1 */
308 dl 1.3 public NavigableSet<E> navigableTailSet(E fromElement) {
309     return new TreeSet<E>(m.navigableTailMap(fromElement));
310     }
311    
312     /**
313 jsr166 1.11 * Equivalent to {@link #navigableSubSet} but with a return type
314     * conforming to the <tt>SortedSet</tt> interface.
315     *
316     * <p>{@inheritDoc}
317     *
318     * @throws ClassCastException {@inheritDoc}
319 dl 1.3 * @throws NullPointerException if <tt>fromElement</tt> or
320 jsr166 1.11 * <tt>toElement</tt> is null and this set uses natural ordering,
321     * or its comparator does not permit null elements
322     * @throws IllegalArgumentException {@inheritDoc}
323 dl 1.3 */
324     public SortedSet<E> subSet(E fromElement, E toElement) {
325     return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
326     }
327    
328     /**
329 jsr166 1.11 * Equivalent to {@link #navigableHeadSet} but with a return type
330     * conforming to the <tt>SortedSet</tt> interface.
331     *
332     * <p>{@inheritDoc}
333 dl 1.3 *
334 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
335     * @throws NullPointerException if <tt>toElement</tt> is null
336     * and this set uses natural ordering, or its comparator does
337     * not permit null elements
338     * @throws IllegalArgumentException {@inheritDoc}
339 dl 1.3 */
340     public SortedSet<E> headSet(E toElement) {
341     return new TreeSet<E>(m.navigableHeadMap(toElement));
342     }
343    
344     /**
345 jsr166 1.11 * Equivalent to {@link #navigableTailSet} but with a return type
346     * conforming to the <tt>SortedSet</tt> interface.
347     *
348     * <p>{@inheritDoc}
349     *
350     * @throws ClassCastException {@inheritDoc}
351     * @throws NullPointerException if <tt>fromElement</tt> is null
352     * and this set uses natural ordering, or its comparator does
353     * not permit null elements
354     * @throws IllegalArgumentException {@inheritDoc}
355 dl 1.3 */
356     public SortedSet<E> tailSet(E fromElement) {
357     return new TreeSet<E>(m.navigableTailMap(fromElement));
358 dl 1.1 }
359    
360     public Comparator<? super E> comparator() {
361     return m.comparator();
362     }
363    
364     /**
365 jsr166 1.11 * @throws NoSuchElementException {@inheritDoc}
366 dl 1.1 */
367     public E first() {
368     return m.firstKey();
369     }
370    
371     /**
372 jsr166 1.11 * @throws NoSuchElementException {@inheritDoc}
373 dl 1.1 */
374     public E last() {
375     return m.lastKey();
376     }
377    
378     // NavigableSet API methods
379    
380     /**
381 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
382     * @throws NullPointerException if the specified element is null and
383     * this set uses natural ordering and is non-empty,
384     * or its comparator does not permit null elements
385 dl 1.1 */
386 jsr166 1.11 public E lower(E e) {
387     return m.lowerKey(e);
388 dl 1.1 }
389    
390     /**
391 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
392     * @throws NullPointerException if the specified element is null and
393     * this set uses natural ordering and is non-empty,
394     * or its comparator does not permit null elements
395 dl 1.1 */
396 jsr166 1.11 public E floor(E e) {
397     return m.floorKey(e);
398 dl 1.1 }
399    
400     /**
401 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
402     * @throws NullPointerException if the specified element is null and
403     * this set uses natural ordering and is non-empty,
404     * or its comparator does not permit null elements
405 dl 1.1 */
406 jsr166 1.11 public E ceiling(E e) {
407     return m.ceilingKey(e);
408 dl 1.1 }
409    
410     /**
411 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
412     * @throws NullPointerException if the specified element is null and
413     * this set uses natural ordering and is non-empty,
414     * or its comparator does not permit null elements
415 dl 1.1 */
416 jsr166 1.7 public E higher(E e) {
417     return m.higherKey(e);
418 dl 1.1 }
419    
420     public E pollFirst() {
421     Map.Entry<E,?> e = m.pollFirstEntry();
422     return (e == null)? null : e.getKey();
423     }
424    
425     public E pollLast() {
426     Map.Entry<E,?> e = m.pollLastEntry();
427     return (e == null)? null : e.getKey();
428     }
429    
430     /**
431     * Returns a shallow copy of this <tt>TreeSet</tt> instance. (The elements
432     * themselves are not cloned.)
433     *
434 jsr166 1.11 * @return a shallow copy of this set
435 dl 1.1 */
436     public Object clone() {
437     TreeSet<E> clone = null;
438     try {
439     clone = (TreeSet<E>) super.clone();
440     } catch (CloneNotSupportedException e) {
441     throw new InternalError();
442     }
443    
444     clone.m = new TreeMap<E,Object>(m);
445    
446     return clone;
447     }
448    
449     /**
450     * Save the state of the <tt>TreeSet</tt> instance to a stream (that is,
451     * serialize it).
452     *
453     * @serialData Emits the comparator used to order this set, or
454 jsr166 1.11 * <tt>null</tt> if it obeys its elements' natural ordering
455     * (Object), followed by the size of the set (the number of
456     * elements it contains) (int), followed by all of its
457     * elements (each an Object) in order (as determined by the
458     * set's Comparator, or by the elements' natural ordering if
459 dl 1.1 * the set has no Comparator).
460     */
461     private void writeObject(java.io.ObjectOutputStream s)
462     throws java.io.IOException {
463     // Write out any hidden stuff
464     s.defaultWriteObject();
465    
466     // Write out Comparator
467     s.writeObject(m.comparator());
468    
469     // Write out size
470     s.writeInt(m.size());
471    
472     // Write out all elements in the proper order.
473     for (Iterator i=m.keySet().iterator(); i.hasNext(); )
474     s.writeObject(i.next());
475     }
476    
477     /**
478     * Reconstitute the <tt>TreeSet</tt> instance from a stream (that is,
479     * deserialize it).
480     */
481     private void readObject(java.io.ObjectInputStream s)
482     throws java.io.IOException, ClassNotFoundException {
483     // Read in any hidden stuff
484     s.defaultReadObject();
485    
486     // Read in Comparator
487 jsr166 1.9 Comparator<? super E> c = (Comparator<? super E>) s.readObject();
488 dl 1.1
489     // Create backing TreeMap
490     TreeMap<E,Object> tm;
491     if (c==null)
492     tm = new TreeMap<E,Object>();
493     else
494     tm = new TreeMap<E,Object>(c);
495     m = tm;
496    
497     // Read in size
498     int size = s.readInt();
499    
500     tm.readTreeSet(size, s, PRESENT);
501     }
502    
503     private static final long serialVersionUID = -2479143000061671589L;
504     }