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