ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeSet.java
Revision: 1.18
Committed: Mon Jul 18 01:14:34 2005 UTC (18 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.17: +10 -10 lines
Log Message:
doc fixes

File Contents

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