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