ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeSet.java
Revision: 1.23
Committed: Fri Apr 21 03:24:07 2006 UTC (18 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.22: +3 -3 lines
Log Message:
&nbsp and @code are immiscible

File Contents

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