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