ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeSet.java
Revision: 1.14
Committed: Tue May 17 22:04:55 2005 UTC (19 years ago) by jsr166
Branch: MAIN
Changes since 1.13: +1 -1 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 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 *
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 }
124
125 /**
126 * 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 * <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 */
139 public TreeSet(Collection<? extends E> c) {
140 this();
141 addAll(c);
142 }
143
144 /**
145 * Constructs a new tree set containing the same elements and
146 * using the same ordering as the specified sorted set.
147 *
148 * @param s sorted set whose elements will comprise the new set
149 * @throws NullPointerException if the specified sorted set is null
150 */
151 public TreeSet(SortedSet<E> s) {
152 this(s.comparator());
153 addAll(s);
154 }
155
156 /**
157 * Returns an iterator over the elements in this set in ascending order.
158 *
159 * @return an iterator over the elements in this set in ascending order
160 */
161 public Iterator<E> iterator() {
162 return m.keySet().iterator();
163 }
164
165 /**
166 * Returns an iterator over the elements in this set in descending order.
167 *
168 * @return an iterator over the elements in this set in descending order
169 */
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 * @return the number of elements in this set (its cardinality)
178 */
179 public int size() {
180 return m.size();
181 }
182
183 /**
184 * Returns <tt>true</tt> if this set contains no elements.
185 *
186 * @return <tt>true</tt> if this set contains no elements
187 */
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 * @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 * @throws ClassCastException if the specified object cannot be compared
198 * 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 */
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 * @param e element to be added to this set
211 * @return <tt>true</tt> if the set did not already contain the specified
212 * element
213 * @throws ClassCastException if the specified object cannot be compared
214 * 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 */
219 public boolean add(E e) {
220 return m.put(e, PRESENT)==null;
221 }
222
223 /**
224 * Removes the specified element from this set if it is present.
225 *
226 * @param o object to be removed from this set, if present
227 * @return <tt>true</tt> if the set contained the specified element
228 * @throws ClassCastException if the specified object cannot be compared
229 * 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 */
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 * The set will be empty after this call returns.
241 */
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 collection containing elements to be added to this set
250 * @return <tt>true</tt> if this set changed as a result of the call
251 * @throws ClassCastException if the elements provided cannot be compared
252 * 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 */
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 SortedSet<? extends E> set = (SortedSet<? extends E>) c;
263 TreeMap<E,Object> map = (TreeMap<E, Object>) m;
264 Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
265 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 * @throws ClassCastException {@inheritDoc}
276 * @throws NullPointerException if <tt>fromElement</tt> or
277 * <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 */
281 public NavigableSet<E> navigableSubSet(E fromElement, E toElement) {
282 return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
283 }
284
285 /**
286 * @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 */
292 public NavigableSet<E> navigableHeadSet(E toElement) {
293 return new TreeSet<E>(m.navigableHeadMap(toElement));
294 }
295
296 /**
297 * @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 */
303 public NavigableSet<E> navigableTailSet(E fromElement) {
304 return new TreeSet<E>(m.navigableTailMap(fromElement));
305 }
306
307 /**
308 * 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 * @throws NullPointerException if <tt>fromElement</tt> or
315 * <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 */
319 public SortedSet<E> subSet(E fromElement, E toElement) {
320 return new TreeSet<E>(m.navigableSubMap(fromElement, toElement));
321 }
322
323 /**
324 * Equivalent to {@link #navigableHeadSet} but with a return type
325 * conforming to the <tt>SortedSet</tt> interface.
326 *
327 * <p>{@inheritDoc}
328 *
329 * @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 */
335 public SortedSet<E> headSet(E toElement) {
336 return new TreeSet<E>(m.navigableHeadMap(toElement));
337 }
338
339 /**
340 * 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 */
351 public SortedSet<E> tailSet(E fromElement) {
352 return new TreeSet<E>(m.navigableTailMap(fromElement));
353 }
354
355 public Comparator<? super E> comparator() {
356 return m.comparator();
357 }
358
359 /**
360 * @throws NoSuchElementException {@inheritDoc}
361 */
362 public E first() {
363 return m.firstKey();
364 }
365
366 /**
367 * @throws NoSuchElementException {@inheritDoc}
368 */
369 public E last() {
370 return m.lastKey();
371 }
372
373 // NavigableSet API methods
374
375 /**
376 * @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 */
381 public E lower(E e) {
382 return m.lowerKey(e);
383 }
384
385 /**
386 * @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 */
391 public E floor(E e) {
392 return m.floorKey(e);
393 }
394
395 /**
396 * @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 */
401 public E ceiling(E e) {
402 return m.ceilingKey(e);
403 }
404
405 /**
406 * @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 */
411 public E higher(E e) {
412 return m.higherKey(e);
413 }
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 * @return a shallow copy of this set
430 */
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 * <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 * 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 Comparator<? super E> c = (Comparator<? super E>) s.readObject();
483
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 }