ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeSet.java
Revision: 1.12
Committed: Tue May 17 04:10:23 2005 UTC (19 years ago) by jsr166
Branch: MAIN
Changes since 1.11: +12 -15 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.12 * Constructs a new, empty tree set, sorted according to the specified
110     * comparator. All elements inserted into the set must be <i>mutually
111     * comparable</i> by the specified comparator: <tt>comparator.compare(e1,
112     * e2)</tt> must not throw a <tt>ClassCastException</tt> for any elements
113     * <tt>e1</tt> and <tt>e2</tt> in the set. If the user attempts to add
114     * an element to the set that violates this constraint, the
115     * <tt>add(Object)</tt> call will throw a <tt>ClassCastException</tt>.
116 jsr166 1.11 *
117     * @param comparator the comparator that will be used to order this set.
118     * If <tt>null</tt>, the {@linkplain Comparable natural
119     * ordering} of the elements will be used.
120     */
121     public TreeSet(Comparator<? super E> comparator) {
122     this(new TreeMap<E,Object>(comparator));
123 dl 1.1 }
124    
125     /**
126 jsr166 1.12 * Constructs a new tree set containing the elements in the specified
127     * collection, sorted according to the <i>natural ordering</i> of its
128     * elements. All elements inserted into the set must implement the
129     * {@link Comparable} interface. Furthermore, all such elements must be
130     * <i>mutually comparable</i>: <tt>e1.compareTo(e2)</tt> must not throw a
131 jsr166 1.11 * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
132     * <tt>e2</tt> in the set.
133     *
134     * @param c collection whose elements will comprise the new set
135     * @throws ClassCastException if the elements in <tt>c</tt> are
136     * not {@link Comparable}, or are not mutually comparable
137     * @throws NullPointerException if the specified collection is null
138 dl 1.1 */
139     public TreeSet(Collection<? extends E> c) {
140     this();
141     addAll(c);
142     }
143    
144     /**
145 jsr166 1.11 * Constructs a new tree set containing the same elements and
146     * using the same ordering as the specified sorted set.
147 dl 1.1 *
148 jsr166 1.11 * @param s sorted set whose elements will comprise the new set
149     * @throws NullPointerException if the specified sorted set is null
150 dl 1.1 */
151     public TreeSet(SortedSet<E> s) {
152     this(s.comparator());
153     addAll(s);
154     }
155    
156     /**
157     * Returns an iterator over the elements in this set. The elements
158     * are returned in ascending order.
159     *
160 jsr166 1.11 * @return an iterator over the elements in this set
161 dl 1.1 */
162     public Iterator<E> iterator() {
163 jsr166 1.11 return m.keySet().iterator();
164 dl 1.1 }
165    
166     /**
167     * Returns an iterator over the elements in this set. The elements
168     * are returned in descending order.
169     *
170 jsr166 1.11 * @return an iterator over the elements in this set
171 dl 1.1 */
172     public Iterator<E> descendingIterator() {
173     return m.descendingKeySet().iterator();
174     }
175    
176     /**
177     * Returns the number of elements in this set (its cardinality).
178     *
179 jsr166 1.11 * @return the number of elements in this set (its cardinality)
180 dl 1.1 */
181     public int size() {
182     return m.size();
183     }
184    
185     /**
186     * Returns <tt>true</tt> if this set contains no elements.
187     *
188 jsr166 1.11 * @return <tt>true</tt> if this set contains no elements
189 dl 1.1 */
190     public boolean isEmpty() {
191     return m.isEmpty();
192     }
193    
194     /**
195     * Returns <tt>true</tt> if this set contains the specified element.
196     *
197 jsr166 1.11 * @param o the object to be checked for containment in this set
198     * @return <tt>true</tt> if this set contains the specified element
199 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
200 jsr166 1.11 * with the elements currently in the set
201     * @throws NullPointerException if the specified element is null and
202     * this set uses natural ordering and is non-empty, or its
203     * comparator does not permit null elements
204 dl 1.1 */
205     public boolean contains(Object o) {
206     return m.containsKey(o);
207     }
208    
209     /**
210     * Adds the specified element to this set if it is not already present.
211     *
212 jsr166 1.11 * @param e element to be added to this set
213 dl 1.1 * @return <tt>true</tt> if the set did not already contain the specified
214 jsr166 1.11 * element
215 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
216 jsr166 1.11 * with the elements currently in the set
217     * @throws NullPointerException if the specified element is null and
218     * this set uses natural ordering and is non-empty, or its
219     * comparator does not permit null elements
220 dl 1.1 */
221 jsr166 1.7 public boolean add(E e) {
222     return m.put(e, PRESENT)==null;
223 dl 1.1 }
224    
225     /**
226     * Removes the specified element from this set if it is present.
227     *
228 jsr166 1.11 * @param o object to be removed from this set, if present
229     * @return <tt>true</tt> if the set contained the specified element
230 dl 1.1 * @throws ClassCastException if the specified object cannot be compared
231 jsr166 1.11 * with the elements currently in the set
232     * @throws NullPointerException if the specified element is null and
233     * this set uses natural ordering and is non-empty, or its
234     * comparator does not permit null elements
235 dl 1.1 */
236     public boolean remove(Object o) {
237     return m.remove(o)==PRESENT;
238     }
239    
240     /**
241     * Removes all of the elements from this set.
242 jsr166 1.11 * The set will be empty after this call returns.
243 dl 1.1 */
244     public void clear() {
245     m.clear();
246     }
247    
248     /**
249     * Adds all of the elements in the specified collection to this set.
250     *
251     * @param c elements to be added
252 jsr166 1.11 * @return <tt>true</tt> if this set changed as a result of the call
253 dl 1.1 * @throws ClassCastException if the elements provided cannot be compared
254 jsr166 1.11 * with the elements currently in the set
255     * @throws NullPointerException if the specified collection is null or
256     * if any element is null and this set uses natural ordering, or
257     * its comparator does not permit null elements
258 dl 1.1 */
259     public boolean addAll(Collection<? extends E> c) {
260     // Use linear-time version if applicable
261     if (m.size()==0 && c.size() > 0 &&
262     c instanceof SortedSet &&
263     m instanceof TreeMap) {
264 jsr166 1.9 SortedSet<? extends E> set = (SortedSet<? extends E>) c;
265 dl 1.1 TreeMap<E,Object> map = (TreeMap<E, Object>) m;
266 jsr166 1.9 Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
267 dl 1.1 Comparator<? super E> mc = map.comparator();
268     if (cc==mc || (cc != null && cc.equals(mc))) {
269     map.addAllForTreeSet(set, PRESENT);
270     return true;
271     }
272     }
273     return super.addAll(c);
274     }
275    
276     /**
277 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
278 dl 1.1 * @throws NullPointerException if <tt>fromElement</tt> or
279 jsr166 1.11 * <tt>toElement</tt> is null and this set uses natural ordering,
280     * or its comparator does not permit null elements
281     * @throws IllegalArgumentException {@inheritDoc}
282 dl 1.1 */
283 dl 1.3 public NavigableSet<E> navigableSubSet(E fromElement, E toElement) {
284     return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
285 dl 1.1 }
286    
287     /**
288 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
289     * @throws NullPointerException if <tt>toElement</tt> is null and
290     * this set uses natural ordering, or its comparator does
291     * not permit null elements
292     * @throws IllegalArgumentException {@inheritDoc}
293 dl 1.1 */
294 dl 1.3 public NavigableSet<E> navigableHeadSet(E toElement) {
295     return new TreeSet<E>(m.navigableHeadMap(toElement));
296 dl 1.1 }
297    
298     /**
299 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
300     * @throws NullPointerException if <tt>fromElement</tt> is null and
301     * this set uses natural ordering, or its comparator does
302     * not permit null elements
303     * @throws IllegalArgumentException {@inheritDoc}
304 dl 1.1 */
305 dl 1.3 public NavigableSet<E> navigableTailSet(E fromElement) {
306     return new TreeSet<E>(m.navigableTailMap(fromElement));
307     }
308    
309     /**
310 jsr166 1.11 * Equivalent to {@link #navigableSubSet} but with a return type
311     * conforming to the <tt>SortedSet</tt> interface.
312     *
313     * <p>{@inheritDoc}
314     *
315     * @throws ClassCastException {@inheritDoc}
316 dl 1.3 * @throws NullPointerException if <tt>fromElement</tt> or
317 jsr166 1.11 * <tt>toElement</tt> is null and this set uses natural ordering,
318     * or its comparator does not permit null elements
319     * @throws IllegalArgumentException {@inheritDoc}
320 dl 1.3 */
321     public SortedSet<E> subSet(E fromElement, E toElement) {
322     return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
323     }
324    
325     /**
326 jsr166 1.11 * Equivalent to {@link #navigableHeadSet} but with a return type
327     * conforming to the <tt>SortedSet</tt> interface.
328     *
329     * <p>{@inheritDoc}
330 dl 1.3 *
331 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
332     * @throws NullPointerException if <tt>toElement</tt> is null
333     * and this set uses natural ordering, or its comparator does
334     * not permit null elements
335     * @throws IllegalArgumentException {@inheritDoc}
336 dl 1.3 */
337     public SortedSet<E> headSet(E toElement) {
338     return new TreeSet<E>(m.navigableHeadMap(toElement));
339     }
340    
341     /**
342 jsr166 1.11 * Equivalent to {@link #navigableTailSet} but with a return type
343     * conforming to the <tt>SortedSet</tt> interface.
344     *
345     * <p>{@inheritDoc}
346     *
347     * @throws ClassCastException {@inheritDoc}
348     * @throws NullPointerException if <tt>fromElement</tt> is null
349     * and this set uses natural ordering, or its comparator does
350     * not permit null elements
351     * @throws IllegalArgumentException {@inheritDoc}
352 dl 1.3 */
353     public SortedSet<E> tailSet(E fromElement) {
354     return new TreeSet<E>(m.navigableTailMap(fromElement));
355 dl 1.1 }
356    
357     public Comparator<? super E> comparator() {
358     return m.comparator();
359     }
360    
361     /**
362 jsr166 1.11 * @throws NoSuchElementException {@inheritDoc}
363 dl 1.1 */
364     public E first() {
365     return m.firstKey();
366     }
367    
368     /**
369 jsr166 1.11 * @throws NoSuchElementException {@inheritDoc}
370 dl 1.1 */
371     public E last() {
372     return m.lastKey();
373     }
374    
375     // NavigableSet API methods
376    
377     /**
378 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
379     * @throws NullPointerException if the specified element is null and
380     * this set uses natural ordering and is non-empty,
381     * or its comparator does not permit null elements
382 dl 1.1 */
383 jsr166 1.11 public E lower(E e) {
384     return m.lowerKey(e);
385 dl 1.1 }
386    
387     /**
388 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
389     * @throws NullPointerException if the specified element is null and
390     * this set uses natural ordering and is non-empty,
391     * or its comparator does not permit null elements
392 dl 1.1 */
393 jsr166 1.11 public E floor(E e) {
394     return m.floorKey(e);
395 dl 1.1 }
396    
397     /**
398 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
399     * @throws NullPointerException if the specified element is null and
400     * this set uses natural ordering and is non-empty,
401     * or its comparator does not permit null elements
402 dl 1.1 */
403 jsr166 1.11 public E ceiling(E e) {
404     return m.ceilingKey(e);
405 dl 1.1 }
406    
407     /**
408 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
409     * @throws NullPointerException if the specified element is null and
410     * this set uses natural ordering and is non-empty,
411     * or its comparator does not permit null elements
412 dl 1.1 */
413 jsr166 1.7 public E higher(E e) {
414     return m.higherKey(e);
415 dl 1.1 }
416    
417     public E pollFirst() {
418     Map.Entry<E,?> e = m.pollFirstEntry();
419     return (e == null)? null : e.getKey();
420     }
421    
422     public E pollLast() {
423     Map.Entry<E,?> e = m.pollLastEntry();
424     return (e == null)? null : e.getKey();
425     }
426    
427     /**
428     * Returns a shallow copy of this <tt>TreeSet</tt> instance. (The elements
429     * themselves are not cloned.)
430     *
431 jsr166 1.11 * @return a shallow copy of this set
432 dl 1.1 */
433     public Object clone() {
434     TreeSet<E> clone = null;
435     try {
436     clone = (TreeSet<E>) super.clone();
437     } catch (CloneNotSupportedException e) {
438     throw new InternalError();
439     }
440    
441     clone.m = new TreeMap<E,Object>(m);
442    
443     return clone;
444     }
445    
446     /**
447     * Save the state of the <tt>TreeSet</tt> instance to a stream (that is,
448     * serialize it).
449     *
450     * @serialData Emits the comparator used to order this set, or
451 jsr166 1.11 * <tt>null</tt> if it obeys its elements' natural ordering
452     * (Object), followed by the size of the set (the number of
453     * elements it contains) (int), followed by all of its
454     * elements (each an Object) in order (as determined by the
455     * set's Comparator, or by the elements' natural ordering if
456 dl 1.1 * the set has no Comparator).
457     */
458     private void writeObject(java.io.ObjectOutputStream s)
459     throws java.io.IOException {
460     // Write out any hidden stuff
461     s.defaultWriteObject();
462    
463     // Write out Comparator
464     s.writeObject(m.comparator());
465    
466     // Write out size
467     s.writeInt(m.size());
468    
469     // Write out all elements in the proper order.
470     for (Iterator i=m.keySet().iterator(); i.hasNext(); )
471     s.writeObject(i.next());
472     }
473    
474     /**
475     * Reconstitute the <tt>TreeSet</tt> instance from a stream (that is,
476     * deserialize it).
477     */
478     private void readObject(java.io.ObjectInputStream s)
479     throws java.io.IOException, ClassNotFoundException {
480     // Read in any hidden stuff
481     s.defaultReadObject();
482    
483     // Read in Comparator
484 jsr166 1.9 Comparator<? super E> c = (Comparator<? super E>) s.readObject();
485 dl 1.1
486     // Create backing TreeMap
487     TreeMap<E,Object> tm;
488     if (c==null)
489     tm = new TreeMap<E,Object>();
490     else
491     tm = new TreeMap<E,Object>(c);
492     m = tm;
493    
494     // Read in size
495     int size = s.readInt();
496    
497     tm.readTreeSet(size, s, PRESENT);
498     }
499    
500     private static final long serialVersionUID = -2479143000061671589L;
501     }