ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166x/ConcurrentSkipListSet.java
Revision: 1.4
Committed: Sat Oct 16 14:49:45 2004 UTC (19 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.3: +75 -14 lines
Log Message:
Improve pollLast* implementation; other minor touchups

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 */
6
7 package jsr166x;
8
9 import java.util.*;
10 import java.util.concurrent.*;
11
12 /**
13 * A scalable concurrent {@link NavigableSet} implementation based on
14 * a {@link ConcurrentSkipListMap}. This class maintains a set in
15 * ascending order, sorted according to the <i>natural order</i> for
16 * the element's class (see {@link Comparable}), or by the comparator
17 * provided at creation time, depending on which constructor is
18 * used.<p>
19 *
20 * This implementation provides expected average <i>log(n)</i> time
21 * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt>
22 * operations and their variants. Insertion, removal, and access
23 * operations safely execute concurrently by multiple
24 * threads. Iterators are <i>weakly consistent</i>, returning elements
25 * reflecting the state of the set at some point at or since the
26 * creation of the iterator. They do <em>not</em> throw {@link
27 * ConcurrentModificationException}, and may procede concurrently with
28 * other operations.
29 *
30 * <p>Beware that, unlike in most collections, the <tt>size</tt>
31 * method is <em>not</em> a constant-time operation. Because of the
32 * asynchronous nature of these sets, determining the current number
33 * of elements requires a traversal of the elements. Additionally, the
34 * bulk operations <tt>addAll</tt>, <tt>removeAll</tt>,
35 * <<tt>retainAll</tt>, and tt>containsAll</tt> are <em>not</em>
36 * guaranteed to be performed atomically. For example, an iterator
37 * operating concurrently with an <tt>addAll</tt> operation might view
38 * only some of the added elements.
39 *
40 * <p>This class and its iterators implement all of the
41 * <em>optional</em> methods of the {@link Set} and {@link Iterator}
42 * interfaces. Like most other concurrent collection implementations,
43 * this class does not permit the use of <tt>null</tt> elements.
44 * because <tt>null</tt> arguments and return values cannot be reliably
45 * distinguished from the absence of elements.
46 *
47 * @author Doug Lea
48 * @param <E> the type of elements maintained by this set
49 */
50 public class ConcurrentSkipListSet<E>
51 extends AbstractSet<E>
52 implements NavigableSet<E>, Cloneable, java.io.Serializable {
53
54 private static final long serialVersionUID = -2479143111061671589L;
55
56 /**
57 * The underlying map. Uses Boolean.TRUE as value for each
58 * element. Note that this class relies on default serialization,
59 * which is a little wasteful in saving all of the useless value
60 * fields of underlying map, but enables this field to be declared
61 * final, which is necessary for thread safety.
62 */
63 private final ConcurrentSkipListMap<E,Object> m;
64
65 /**
66 * Constructs a new, empty set, sorted according to the elements' natural
67 * order.
68 */
69 public ConcurrentSkipListSet() {
70 m = new ConcurrentSkipListMap<E,Object>();
71 }
72
73 /**
74 * Constructs a new, empty set, sorted according to the specified
75 * comparator.
76 *
77 * @param c the comparator that will be used to sort this set. A
78 * <tt>null</tt> value indicates that the elements' <i>natural
79 * ordering</i> should be used.
80 */
81 public ConcurrentSkipListSet(Comparator<? super E> c) {
82 m = new ConcurrentSkipListMap<E,Object>(c);
83 }
84
85 /**
86 * Constructs a new set containing the elements in the specified
87 * collection, sorted according to the elements' <i>natural order</i>.
88 *
89 * @param c The elements that will comprise the new set.
90 *
91 * @throws ClassCastException if the elements in the specified
92 * collection are not comparable, or are not mutually comparable.
93 * @throws NullPointerException if the specified collection is
94 * <tt>null</tt>.
95 */
96 public ConcurrentSkipListSet(Collection<? extends E> c) {
97 m = new ConcurrentSkipListMap<E,Object>();
98 addAll(c);
99 }
100
101 /**
102 * Constructs a new set containing the same elements as the specified
103 * sorted set, sorted according to the same ordering.
104 *
105 * @param s sorted set whose elements will comprise the new set.
106 * @throws NullPointerException if the specified sorted set is
107 * <tt>null</tt>.
108 */
109 public ConcurrentSkipListSet(SortedSet<E> s) {
110 m = new ConcurrentSkipListMap<E,Object>(s.comparator());
111 addAll(s);
112 }
113
114 /**
115 * Returns a shallow copy of this set. (The elements themselves
116 * are not cloned.)
117 *
118 * @return a shallow copy of this set.
119 */
120 public Object clone() {
121 ConcurrentSkipListSet<E> clone = null;
122 try {
123 clone = (ConcurrentSkipListSet<E>) super.clone();
124 } catch (CloneNotSupportedException e) {
125 throw new InternalError();
126 }
127
128 clone.m.initialize();
129 clone.addAll(this);
130 return clone;
131 }
132
133 /* ---------------- Set operations -------------- */
134
135 /**
136 * Returns the number of elements in this set. If this set
137 * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
138 * returns <tt>Integer.MAX_VALUE</tt>.
139 *
140 * <p>Beware that, unlike in most collections, this method is
141 * <em>NOT</em> a constant-time operation. Because of the
142 * asynchronous nature of these sets, determining the current
143 * number of elements requires traversing them all to count them.
144 * Additionally, it is possible for the size to change during
145 * execution of this method, in which case the returned result
146 * will be inaccurate. Thus, this method is typically not very
147 * useful in concurrent applications.
148 *
149 * @return the number of elements in this set.
150 */
151 public int size() {
152 return m.size();
153 }
154
155 /**
156 * Returns <tt>true</tt> if this set contains no elements.
157 * @return <tt>true</tt> if this set contains no elements.
158 */
159 public boolean isEmpty() {
160 return m.isEmpty();
161 }
162
163 /**
164 * Returns <tt>true</tt> if this set contains the specified element.
165 *
166 * @param o the object to be checked for containment in this set.
167 * @return <tt>true</tt> if this set contains the specified element.
168 *
169 * @throws ClassCastException if the specified object cannot be compared
170 * with the elements currently in the set.
171 * @throws NullPointerException if o is <tt>null</tt>.
172 */
173 public boolean contains(Object o) {
174 return m.containsKey(o);
175 }
176
177 /**
178 * Adds the specified element to this set if it is not already present.
179 *
180 * @param o element to be added to this set.
181 * @return <tt>true</tt> if the set did not already contain the specified
182 * element.
183 *
184 * @throws ClassCastException if the specified object cannot be compared
185 * with the elements currently in the set.
186 * @throws NullPointerException if o is <tt>null</tt>.
187 */
188 public boolean add(E o) {
189 return m.putIfAbsent(o, Boolean.TRUE) == null;
190 }
191
192 /**
193 * Removes the specified element from this set if it is present.
194 *
195 * @param o object to be removed from this set, if present.
196 * @return <tt>true</tt> if the set contained the specified element.
197 *
198 * @throws ClassCastException if the specified object cannot be compared
199 * with the elements currently in the set.
200 * @throws NullPointerException if o is <tt>null</tt>.
201 */
202 public boolean remove(Object o) {
203 return m.removep(o);
204 }
205
206 /**
207 * Removes all of the elements from this set.
208 */
209 public void clear() {
210 m.clear();
211 }
212
213 /**
214 * Returns an iterator over the elements in this set. The elements
215 * are returned in ascending order.
216 *
217 * @return an iterator over the elements in this set.
218 */
219 public Iterator<E> iterator() {
220 return m.keyIterator();
221 }
222
223 /* ---------------- AbstractSet Overrides -------------- */
224
225 /**
226 * Compares the specified object with this set for equality. Returns
227 * <tt>true</tt> if the specified object is also a set, the two sets
228 * have the same size, and every member of the specified set is
229 * contained in this set (or equivalently, every member of this set is
230 * contained in the specified set). This definition ensures that the
231 * equals method works properly across different implementations of the
232 * set interface.
233 *
234 * @param o Object to be compared for equality with this set.
235 * @return <tt>true</tt> if the specified Object is equal to this set.
236 */
237 public boolean equals(Object o) {
238 // Override AbstractSet version to avoid calling size()
239 if (o == this)
240 return true;
241 if (!(o instanceof Set))
242 return false;
243 Collection c = (Collection) o;
244 try {
245 return containsAll(c) && c.containsAll(this);
246 } catch(ClassCastException unused) {
247 return false;
248 } catch(NullPointerException unused) {
249 return false;
250 }
251 }
252
253 /**
254 * Removes from this set all of its elements that are contained in
255 * the specified collection. If the specified collection is also
256 * a set, this operation effectively modifies this set so that its
257 * value is the <i>asymmetric set difference</i> of the two sets.
258 *
259 * @param c collection that defines which elements will be removed from
260 * this set.
261 * @return <tt>true</tt> if this set changed as a result of the call.
262 *
263 * @throws ClassCastException if the types of one or more elements in this
264 * set are incompatible with the specified collection
265 * @throws NullPointerException if the specified collection, or any
266 * of its elements are <tt>null</tt>.
267 */
268 public boolean removeAll(Collection<?> c) {
269 // Override AbstractSet version to avoid unnecessary call to size()
270 boolean modified = false;
271 for (Iterator<?> i = c.iterator(); i.hasNext(); )
272 if (remove(i.next()))
273 modified = true;
274 return modified;
275 }
276
277 /* ---------------- Relational operations -------------- */
278
279 /**
280 * Returns an element greater than or equal to the given element, or
281 * <tt>null</tt> if there is no such element.
282 *
283 * @param o the value to match
284 * @return an element greater than or equal to given element, or
285 * <tt>null</tt> if there is no such element.
286 * @throws ClassCastException if o cannot be compared with the elements
287 * currently in the set.
288 * @throws NullPointerException if o is <tt>null</tt>
289 */
290 public E ceiling(E o) {
291 return m.ceilingKey(o);
292 }
293
294 /**
295 * Returns an element strictly less than the given element, or
296 * <tt>null</tt> if there is no such element.
297 *
298 * @param o the value to match
299 * @return the greatest element less than the given element, or
300 * <tt>null</tt> if there is no such element.
301 * @throws ClassCastException if o cannot be compared with the elements
302 * currently in the set.
303 * @throws NullPointerException if o is <tt>null</tt>.
304 */
305 public E lower(E o) {
306 return m.lowerKey(o);
307 }
308
309 /**
310 * Returns an element less than or equal to the given element, or
311 * <tt>null</tt> if there is no such element.
312 *
313 * @param o the value to match
314 * @return the greatest element less than or equal to given
315 * element, or <tt>null</tt> if there is no such element.
316 * @throws ClassCastException if o cannot be compared with the elements
317 * currently in the set.
318 * @throws NullPointerException if o is <tt>null</tt>.
319 */
320 public E floor(E o) {
321 return m.floorKey(o);
322 }
323
324 /**
325 * Returns an element strictly greater than the given element, or
326 * <tt>null</tt> if there is no such element.
327 *
328 * @param o the value to match
329 * @return the least element greater than the given element, or
330 * <tt>null</tt> if there is no such element.
331 * @throws ClassCastException if o cannot be compared with the elements
332 * currently in the set.
333 * @throws NullPointerException if o is <tt>null</tt>.
334 */
335 public E higher(E o) {
336 return m.higherKey(o);
337 }
338
339 /**
340 * Retrieves and removes the first (lowest) element.
341 *
342 * @return the least element, or <tt>null</tt> if empty.
343 */
344 public E pollFirst() {
345 return m.removeFirstKey();
346 }
347
348 /**
349 * Retrieves and removes the last (highest) element.
350 *
351 * @return the last element, or <tt>null</tt> if empty.
352 */
353 public E pollLast() {
354 return m.removeLastKey();
355 }
356
357
358 /* ---------------- SortedSet operations -------------- */
359
360
361 /**
362 * Returns the comparator used to order this set, or <tt>null</tt>
363 * if this set uses its elements natural ordering.
364 *
365 * @return the comparator used to order this set, or <tt>null</tt>
366 * if this set uses its elements natural ordering.
367 */
368 public Comparator<? super E> comparator() {
369 return m.comparator();
370 }
371
372 /**
373 * Returns the first (lowest) element currently in this set.
374 *
375 * @return the first (lowest) element currently in this set.
376 * @throws NoSuchElementException sorted set is empty.
377 */
378 public E first() {
379 return m.firstKey();
380 }
381
382 /**
383 * Returns the last (highest) element currently in this set.
384 *
385 * @return the last (highest) element currently in this set.
386 * @throws NoSuchElementException sorted set is empty.
387 */
388 public E last() {
389 return m.lastKey();
390 }
391
392
393
394 /**
395 * Returns a view of the portion of this set whose elements range from
396 * <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>, exclusive. (If
397 * <tt>fromElement</tt> and <tt>toElement</tt> are equal, the returned
398 * sorted set is empty.) The returned sorted set is backed by this set,
399 * so changes in the returned sorted set are reflected in this set, and
400 * vice-versa.
401 * @param fromElement low endpoint (inclusive) of the subSet.
402 * @param toElement high endpoint (exclusive) of the subSet.
403 * @return a view of the portion of this set whose elements range from
404 * <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>,
405 * exclusive.
406 * @throws ClassCastException if <tt>fromElement</tt> and
407 * <tt>toElement</tt> cannot be compared to one another using
408 * this set's comparator (or, if the set has no comparator,
409 * using natural ordering).
410 * @throws IllegalArgumentException if <tt>fromElement</tt> is
411 * greater than <tt>toElement</tt>.
412 * @throws NullPointerException if <tt>fromElement</tt> or
413 * <tt>toElement</tt> is <tt>null</tt>.
414 */
415 public NavigableSet<E> subSet(E fromElement, E toElement) {
416 return new ConcurrentSkipListSubSet<E>(m, fromElement, toElement);
417 }
418
419 /**
420 * Returns a view of the portion of this set whose elements are strictly
421 * less than <tt>toElement</tt>. The returned sorted set is backed by
422 * this set, so changes in the returned sorted set are reflected in this
423 * set, and vice-versa.
424 * @param toElement high endpoint (exclusive) of the headSet.
425 * @return a view of the portion of this set whose elements are strictly
426 * less than toElement.
427 * @throws ClassCastException if <tt>toElement</tt> is not compatible
428 * with this set's comparator (or, if the set has no comparator,
429 * if <tt>toElement</tt> does not implement <tt>Comparable</tt>).
430 * @throws NullPointerException if <tt>toElement</tt> is <tt>null</tt>.
431 */
432 public NavigableSet<E> headSet(E toElement) {
433 return new ConcurrentSkipListSubSet<E>(m, null, toElement);
434 }
435
436
437 /**
438 * Returns a view of the portion of this set whose elements are
439 * greater than or equal to <tt>fromElement</tt>. The returned
440 * sorted set is backed by this set, so changes in the returned
441 * sorted set are reflected in this set, and vice-versa.
442 * @param fromElement low endpoint (inclusive) of the tailSet.
443 * @return a view of the portion of this set whose elements are
444 * greater than or equal to <tt>fromElement</tt>.
445 * @throws ClassCastException if <tt>fromElement</tt> is not
446 * compatible with this set's comparator (or, if the set has no
447 * comparator, if <tt>fromElement</tt> does not implement
448 * <tt>Comparable</tt>).
449 * @throws NullPointerException if <tt>fromElement</tt> is <tt>null</tt>.
450 */
451 public NavigableSet<E> tailSet(E fromElement) {
452 return new ConcurrentSkipListSubSet<E>(m, fromElement, null);
453 }
454
455 /**
456 * Subsets returned by {@link ConcurrentSkipListSet} subset operations
457 * represent a subrange of elements of their underlying
458 * sets. Instances of this class support all methods of their
459 * underlying sets, differing in that elements outside their range are
460 * ignored, and attempts to add elements outside their ranges result
461 * in {@link IllegalArgumentException}. Instances of this class are
462 * constructed only using the <tt>subSet</tt>, <tt>headSet</tt>, and
463 * <tt>tailSet</tt> methods of their underlying sets.
464 *
465 */
466 static class ConcurrentSkipListSubSet<E>
467 extends AbstractSet<E>
468 implements NavigableSet<E>, java.io.Serializable {
469
470 private static final long serialVersionUID = -7647078645896651609L;
471
472 /** The underlying submap */
473 private final ConcurrentSkipListMap.ConcurrentSkipListSubMap<E,Object> s;
474
475 /**
476 * Creates a new submap.
477 * @param fromElement inclusive least value, or <tt>null</tt> if from start
478 * @param toElement exclusive upper bound or <tt>null</tt> if to end
479 * @throws IllegalArgumentException if fromElement and toElement
480 * nonnull and fromElement greater than toElement
481 */
482 ConcurrentSkipListSubSet(ConcurrentSkipListMap<E,Object> map,
483 E fromElement, E toElement) {
484 s = new ConcurrentSkipListMap.ConcurrentSkipListSubMap<E,Object>(map, fromElement,
485 toElement);
486 }
487
488 /**
489 * Returns the number of elements in this set. If this set
490 * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
491 * returns <tt>Integer.MAX_VALUE</tt>.
492 *
493 * <p>Beware that, unlike in most collections, this method is
494 * <em>NOT</em> a constant-time operation. Because of the
495 * asynchronous nature of these sets, determining the current
496 * number of elements requires traversing them all to count them.
497 * Additionally, it is possible for the size to change during
498 * execution of this method, in which case the returned result
499 * will be inaccurate. Thus, this method is typically not very
500 * useful in concurrent applications.
501 *
502 * @return the number of elements in this set.
503 */
504 public int size() {
505 return s.size();
506 }
507
508 /**
509 * Returns <tt>true</tt> if this set contains no elements.
510 * @return <tt>true</tt> if this set contains no elements.
511 */
512 public boolean isEmpty() {
513 return s.isEmpty();
514 }
515
516 /**
517 * Returns <tt>true</tt> if this set contains the specified
518 * element.
519 *
520 * @param o the object to be checked for containment in this
521 * set.
522 * @return <tt>true</tt> if this set contains the specified
523 * element.
524 *
525 * @throws ClassCastException if the specified object cannot
526 * be compared with the elements currently in the set.
527 * @throws NullPointerException if o is <tt>null</tt>.
528 */
529 public boolean contains(Object o) {
530 return s.containsKey(o);
531 }
532
533
534 /**
535 * Adds the specified element to this set if it is not already
536 * present.
537 *
538 * @param o element to be added to this set.
539 * @return <tt>true</tt> if the set did not already contain
540 * the specified element.
541 *
542 * @throws ClassCastException if the specified object cannot
543 * be compared with the elements currently in the set.
544 * @throws IllegalArgumentException if o is outside the range
545 * of this subset.
546 * @throws NullPointerException if o is <tt>null</tt>.
547 */
548 public boolean add(E o) {
549 return s.put(o, Boolean.TRUE) == null;
550 }
551
552 /**
553 * Removes the specified element from this set if it is
554 * present.
555 *
556 * @param o object to be removed from this set, if present.
557 * @return <tt>true</tt> if the set contained the specified element.
558 *
559 * @throws ClassCastException if the specified object cannot
560 * be compared with the elements currently in the set.
561 * @throws NullPointerException if o is <tt>null</tt>.
562 */
563 public boolean remove(Object o) {
564 return s.remove(o) != null;
565 }
566
567 /**
568 * Removes all of the elements from this set.
569 */
570 public void clear() {
571 s.clear();
572 }
573
574 /**
575 * Returns an iterator over the elements in this set. The elements
576 * are returned in ascending order.
577 *
578 * @return an iterator over the elements in this set.
579 */
580 public Iterator<E> iterator() {
581 return s.keySet().iterator();
582 }
583
584 /**
585 * Returns an element greater than or equal to the given
586 * element, or <tt>null</tt> if there is no such element.
587 *
588 * @param o the value to match
589 * @return an element greater than or equal to given element, or <tt>null</tt>
590 * if there is no such element.
591 * @throws ClassCastException if o cannot be compared with the
592 * elements currently in the set.
593 * @throws NullPointerException if o is <tt>null</tt>
594 */
595 public E ceiling(E o) {
596 E key = o;
597 E least = s.getLeast();
598 if (least != null && s.getMap().compare(o, least) < 0)
599 key = least;
600 E k = s.getMap().ceilingKey(key);
601 return (k != null && s.inHalfOpenRange(k))? k : null;
602 }
603
604 /**
605 * Returns an element strictly less than the given element, or <tt>null</tt> if
606 * there is no such element.
607 *
608 * @param o the value to match
609 * @return the greatest element less than the given element, or
610 * <tt>null</tt> if there is no such element.
611 * @throws ClassCastException if o cannot be compared with the
612 * elements currently in the set.
613 * @throws NullPointerException if o is <tt>null</tt>.
614 */
615 public E lower(E o) {
616 E k = s.getMap().lowerKey(o);
617 return (k != null && s.inHalfOpenRange(k))? k : null;
618 }
619
620 /**
621 * Returns an element less than or equal to the given element, or <tt>null</tt>
622 * if there is no such element.
623 *
624 * @param o the value to match
625 * @return the greatest element less than or equal to given
626 * element, or <tt>null</tt> if there is no such element.
627 * @throws ClassCastException if o cannot be compared with the
628 * elements currently in the set.
629 * @throws NullPointerException if o is <tt>null</tt>.
630 */
631 public E floor(E o) {
632 E k = s.getMap().floorKey(o);
633 return (k != null && s.inHalfOpenRange(k))? k : null;
634 }
635
636 /**
637 * Returns an element strictly greater than the given element, or <tt>null</tt>
638 * if there is no such element.
639 *
640 * @param o the value to match
641 * @return the least element greater than the given element, or
642 * <tt>null</tt> if there is no such element.
643 * @throws ClassCastException if o cannot be compared with the
644 * elements currently in the set.
645 * @throws NullPointerException if o is <tt>null</tt>.
646 */
647 public E higher(E o) {
648 E k;
649 E least = s.getLeast();
650 if (least != null && s.getMap().compare(o, least) < 0)
651 k = s.getMap().ceilingKey(least);
652 else
653 k = s.getMap().higherKey(o);
654 return (k != null && s.inHalfOpenRange(k))? k : null;
655 }
656
657 /**
658 * Retrieves and removes the first (lowest) element.
659 *
660 * @return the first element, or <tt>null</tt> if empty.
661 */
662 public E pollFirst() {
663 for (;;) {
664 E k = s.lowestKey();
665 if (k == null)
666 return null;
667 if (remove(k))
668 return k;
669 }
670 }
671
672 /**
673 * Retrieves and removes the last (highest) element.
674 *
675 * @return the last element, or <tt>null</tt> if empty.
676 */
677 public E pollLast() {
678 for (;;) {
679 E k = s.highestKey();
680 if (k == null)
681 return null;
682 if (remove(k))
683 return k;
684 }
685 }
686
687 /**
688 * Returns the comparator used to order this set, or <tt>null</tt>
689 * if this set uses its elements natural ordering.
690 *
691 * @return the comparator used to order this set, or <tt>null</tt>
692 * if this set uses its elements natural ordering.
693 */
694 public Comparator<? super E> comparator() {
695 return s.comparator();
696 }
697
698 /**
699 * Returns the first (lowest) element currently in this set.
700 *
701 * @return the first (lowest) element currently in this set.
702 * @throws NoSuchElementException sorted set is empty.
703 */
704 public E first() {
705 return s.firstKey();
706 }
707
708 /**
709 * Returns the last (highest) element currently in this set.
710 *
711 * @return the last (highest) element currently in this set.
712 * @throws NoSuchElementException sorted set is empty.
713 */
714 public E last() {
715 return s.lastKey();
716 }
717
718 /**
719 * Returns a view of the portion of this set whose elements
720 * range from <tt>fromElement</tt>, inclusive, to
721 * <tt>toElement</tt>, exclusive. (If <tt>fromElement</tt>
722 * and <tt>toElement</tt> are equal, the returned sorted set
723 * is empty.) The returned sorted set is backed by this set,
724 * so changes in the returned sorted set are reflected in this
725 * set, and vice-versa.
726 * @param fromElement low endpoint (inclusive) of the subSet.
727 * @param toElement high endpoint (exclusive) of the subSet.
728 * @return a view of the portion of this set whose elements
729 * range from <tt>fromElement</tt>, inclusive, to
730 * <tt>toElement</tt>, exclusive.
731 * @throws ClassCastException if <tt>fromElement</tt> and
732 * <tt>toElement</tt> cannot be compared to one another using
733 * this set's comparator (or, if the set has no comparator,
734 * using natural ordering).
735 * @throws IllegalArgumentException if <tt>fromElement</tt> is
736 * greater than <tt>toElement</tt> or either key is outside
737 * the range of this set.
738 * @throws NullPointerException if <tt>fromElement</tt> or
739 * <tt>toElement</tt> is <tt>null</tt>.
740 */
741 public NavigableSet<E> subSet(E fromElement,
742 E toElement) {
743 if (!s.inOpenRange(fromElement) || !s.inOpenRange(toElement))
744 throw new IllegalArgumentException("element out of range");
745 return new ConcurrentSkipListSubSet<E>(s.getMap(),
746 fromElement, toElement);
747 }
748
749 /**
750 * Returns a view of the portion of this set whose elements are
751 * strictly less than <tt>toElement</tt>. The returned sorted set
752 * is backed by this set, so changes in the returned sorted set
753 * are reflected in this set, and vice-versa.
754 * @param toElement high endpoint (exclusive) of the headSet.
755 * @return a view of the portion of this set whose elements
756 * are strictly less than toElement.
757 * @throws ClassCastException if <tt>toElement</tt> is not
758 * compatible with this set's comparator (or, if the set has
759 * no comparator, if <tt>toElement</tt> does not implement
760 * <tt>Comparable</tt>).
761 * @throws IllegalArgumentException if <tt>toElement</tt> is
762 * outside the range of this set.
763 * @throws NullPointerException if <tt>toElement</tt> is
764 * <tt>null</tt>.
765 */
766 public NavigableSet<E> headSet(E toElement) {
767 E least = s.getLeast();
768 if (!s.inOpenRange(toElement))
769 throw new IllegalArgumentException("element out of range");
770 return new ConcurrentSkipListSubSet<E>(s.getMap(),
771 least, toElement);
772 }
773
774 /**
775 * Returns a view of the portion of this set whose elements
776 * are greater than or equal to <tt>fromElement</tt>. The
777 * returned sorted set is backed by this set, so changes in
778 * the returned sorted set are reflected in this set, and
779 * vice-versa.
780 * @param fromElement low endpoint (inclusive) of the tailSet.
781 * @return a view of the portion of this set whose elements
782 * are greater than or equal to <tt>fromElement</tt>.
783 * @throws ClassCastException if <tt>fromElement</tt> is not
784 * compatible with this set's comparator (or, if the set has
785 * no comparator, if <tt>fromElement</tt> does not implement
786 * <tt>Comparable</tt>).
787 * @throws IllegalArgumentException if <tt>fromElement</tt> is
788 * outside the range of this set.
789 * @throws NullPointerException if <tt>fromElement</tt> is
790 * <tt>null</tt>.
791 */
792 public NavigableSet<E> tailSet(E fromElement) {
793 E fence = s.getFence();
794 if (!s.inOpenRange(fromElement))
795 throw new IllegalArgumentException("element out of range");
796 return new ConcurrentSkipListSubSet<E>(s.getMap(),
797 fromElement, fence);
798 }
799 }
800 }