ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeMap.java
Revision: 1.14
Committed: Mon May 16 08:13:36 2005 UTC (19 years ago) by jsr166
Branch: MAIN
Changes since 1.13: +260 -513 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 Red-Black tree based {@link NavigableMap} implementation.
12 * The map is sorted according to the {@linkplain Comparable natural
13 * ordering} of its keys, or by a {@link Comparator} provided at map
14 * creation time, depending on which constructor is used.
15 *
16 * <p>This implementation provides guaranteed log(n) time cost for the
17 * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and <tt>remove</tt>
18 * operations. Algorithms are adaptations of those in Cormen, Leiserson, and
19 * Rivest's <I>Introduction to Algorithms</I>.
20 *
21 * <p>Note that the ordering maintained by a sorted map (whether or not an
22 * explicit comparator is provided) must be <i>consistent with equals</i> if
23 * this sorted map is to correctly implement the <tt>Map</tt> interface. (See
24 * <tt>Comparable</tt> or <tt>Comparator</tt> for a precise definition of
25 * <i>consistent with equals</i>.) This is so because the <tt>Map</tt>
26 * interface is defined in terms of the equals operation, but a map performs
27 * all key comparisons using its <tt>compareTo</tt> (or <tt>compare</tt>)
28 * method, so two keys that are deemed equal by this method are, from the
29 * standpoint of the sorted map, equal. The behavior of a sorted map
30 * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
31 * just fails to obey the general contract of the <tt>Map</tt> interface.
32 *
33 * <p><b>Note that this implementation is not synchronized.</b> If multiple
34 * threads access a map concurrently, and at least one of the threads modifies
35 * the map structurally, it <i>must</i> be synchronized externally. (A
36 * structural modification is any operation that adds or deletes one or more
37 * mappings; merely changing the value associated with an existing key is not
38 * a structural modification.) This is typically accomplished by
39 * synchronizing on some object that naturally encapsulates the map. If no
40 * such object exists, the map should be "wrapped" using the
41 * <tt>Collections.synchronizedMap</tt> method. This is best done at creation
42 * time, to prevent accidental unsynchronized access to the map:
43 * <pre>
44 * Map m = Collections.synchronizedMap(new TreeMap(...));
45 * </pre>
46 *
47 * <p>The iterators returned by the <tt>iterator</tt> method of the collections
48 * returned by all of this class's "collection view methods" are
49 * <i>fail-fast</i>: if the map is structurally modified at any time after the
50 * iterator is created, in any way except through the iterator's own
51 * <tt>remove</tt> method, the iterator will throw a {@link
52 * ConcurrentModificationException}. Thus, in the face of concurrent
53 * modification, the iterator fails quickly and cleanly, rather than risking
54 * arbitrary, non-deterministic behavior at an undetermined time in the future.
55 *
56 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
57 * as it is, generally speaking, impossible to make any hard guarantees in the
58 * presence of unsynchronized concurrent modification. Fail-fast iterators
59 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
60 * Therefore, it would be wrong to write a program that depended on this
61 * exception for its correctness: <i>the fail-fast behavior of iterators
62 * should be used only to detect bugs.</i>
63 *
64 * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
65 * and its views represent snapshots of mappings at the time they were
66 * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
67 * method. (Note however that it is possible to change mappings in the
68 * associated map using <tt>put</tt>.)
69 *
70 * <p>This class is a member of the
71 * <a href="{@docRoot}/../guide/collections/index.html">
72 * Java Collections Framework</a>.
73 *
74 * @param <K> the type of keys maintained by this map
75 * @param <V> the type of mapped values
76 *
77 * @author Josh Bloch and Doug Lea
78 * @version %I%, %G%
79 * @see Map
80 * @see HashMap
81 * @see Hashtable
82 * @see Comparable
83 * @see Comparator
84 * @see Collection
85 * @see Collections#synchronizedMap(Map)
86 * @since 1.2
87 */
88
89 public class TreeMap<K,V>
90 extends AbstractMap<K,V>
91 implements NavigableMap<K,V>, Cloneable, java.io.Serializable
92 {
93 /**
94 * The comparator used to maintain order in this tree map, or
95 * null if it uses the natural ordering of its keys.
96 *
97 * @serial
98 */
99 private Comparator<? super K> comparator = null;
100
101 private transient Entry<K,V> root = null;
102
103 /**
104 * The number of entries in the tree
105 */
106 private transient int size = 0;
107
108 /**
109 * The number of structural modifications to the tree.
110 */
111 private transient int modCount = 0;
112
113 private void incrementSize() { modCount++; size++; }
114 private void decrementSize() { modCount++; size--; }
115
116 /**
117 * Constructs a new, empty tree map, using the natural ordering of its
118 * keys. All keys inserted into the map must implement the {@link
119 * Comparable} interface. Furthermore, all such keys must be
120 * <i>mutually comparable</i>: <tt>k1.compareTo(k2)</tt> must not throw
121 * a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
122 * <tt>k2</tt> in the map. If the user attempts to put a key into the
123 * map that violates this constraint (for example, the user attempts to
124 * put a string key into a map whose keys are integers), the
125 * <tt>put(Object key, Object value)</tt> call will throw a
126 * <tt>ClassCastException</tt>.
127 */
128 public TreeMap() {
129 }
130
131 /**
132 * Constructs a new, empty tree map, ordered according to the given
133 * comparator. All keys inserted into the map must be <i>mutually
134 * comparable</i> by the given comparator: <tt>comparator.compare(k1,
135 * k2)</tt> must not throw a <tt>ClassCastException</tt> for any keys
136 * <tt>k1</tt> and <tt>k2</tt> in the map. If the user attempts to put
137 * a key into the map that violates this constraint, the <tt>put(Object
138 * key, Object value)</tt> call will throw a
139 * <tt>ClassCastException</tt>.
140 *
141 * @param comparator the comparator that will be used to order this map.
142 * If <tt>null</tt>, the {@linkplain Comparable natural
143 * ordering} of the keys will be used.
144 */
145 public TreeMap(Comparator<? super K> comparator) {
146 this.comparator = comparator;
147 }
148
149 /**
150 * Constructs a new tree map containing the same mappings as the given
151 * map, ordered according to the <i>natural ordering</i> of its keys.
152 * All keys inserted into the new map must implement the {@link
153 * Comparable} interface. Furthermore, all such keys must be
154 * <i>mutually comparable</i>: <tt>k1.compareTo(k2)</tt> must not throw
155 * a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
156 * <tt>k2</tt> in the map. This method runs in n*log(n) time.
157 *
158 * @param m the map whose mappings are to be placed in this map
159 * @throws ClassCastException if the keys in m are not {@link Comparable},
160 * or are not mutually comparable
161 * @throws NullPointerException if the specified map is null
162 */
163 public TreeMap(Map<? extends K, ? extends V> m) {
164 putAll(m);
165 }
166
167 /**
168 * Constructs a new tree map containing the same mappings and
169 * using the same ordering as the specified sorted map. This
170 * method runs in linear time.
171 *
172 * @param m the sorted map whose mappings are to be placed in this map,
173 * and whose comparator is to be used to sort this map
174 * @throws NullPointerException if the specified map is null
175 */
176 public TreeMap(SortedMap<K, ? extends V> m) {
177 comparator = m.comparator();
178 try {
179 buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
180 } catch (java.io.IOException cannotHappen) {
181 } catch (ClassNotFoundException cannotHappen) {
182 }
183 }
184
185
186 // Query Operations
187
188 /**
189 * Returns the number of key-value mappings in this map.
190 *
191 * @return the number of key-value mappings in this map
192 */
193 public int size() {
194 return size;
195 }
196
197 /**
198 * Returns <tt>true</tt> if this map contains a mapping for the specified
199 * key.
200 *
201 * @param key key whose presence in this map is to be tested
202 * @return <tt>true</tt> if this map contains a mapping for the
203 * specified key
204 * @throws ClassCastException if the specified key cannot be compared
205 * with the keys currently in the map
206 * @throws NullPointerException if the specified key is null
207 * and this map uses natural ordering, or its comparator
208 * does not permit null keys
209 */
210 public boolean containsKey(Object key) {
211 return getEntry(key) != null;
212 }
213
214 /**
215 * Returns <tt>true</tt> if this map maps one or more keys to the
216 * specified value. More formally, returns <tt>true</tt> if and only if
217 * this map contains at least one mapping to a value <tt>v</tt> such
218 * that <tt>(value==null ? v==null : value.equals(v))</tt>. This
219 * operation requires time linear in the map size.
220 *
221 * @param value value whose presence in this map is to be tested
222 * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
223 * <tt>false</tt> otherwise
224 * @since 1.2
225 */
226 public boolean containsValue(Object value) {
227 return (root==null ? false :
228 (value==null ? valueSearchNull(root)
229 : valueSearchNonNull(root, value)));
230 }
231
232 private boolean valueSearchNull(Entry n) {
233 if (n.value == null)
234 return true;
235
236 // Check left and right subtrees for value
237 return (n.left != null && valueSearchNull(n.left)) ||
238 (n.right != null && valueSearchNull(n.right));
239 }
240
241 private boolean valueSearchNonNull(Entry n, Object value) {
242 // Check this node for the value
243 if (value.equals(n.value))
244 return true;
245
246 // Check left and right subtrees for value
247 return (n.left != null && valueSearchNonNull(n.left, value)) ||
248 (n.right != null && valueSearchNonNull(n.right, value));
249 }
250
251 /**
252 * Returns the value to which this map maps the specified key, or
253 * <tt>null</tt> if the map contains no mapping for the key. A return
254 * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
255 * map contains no mapping for the key; it's also possible that the map
256 * explicitly maps the key to <tt>null</tt>. The {@link #containsKey}
257 * operation may be used to distinguish these two cases.
258 *
259 * @param key key whose associated value is to be returned
260 * @return the value to which this map maps the specified key, or
261 * <tt>null</tt> if the map contains no mapping for the key
262 * @throws ClassCastException if the specified key cannot be compared
263 * with the keys currently in the map
264 * @throws NullPointerException if the specified key is null
265 * and this map uses natural ordering, or its comparator
266 * does not permit null keys
267 */
268 public V get(Object key) {
269 Entry<K,V> p = getEntry(key);
270 return (p==null ? null : p.value);
271 }
272
273 public Comparator<? super K> comparator() {
274 return comparator;
275 }
276
277 /**
278 * @throws NoSuchElementException {@inheritDoc}
279 */
280 public K firstKey() {
281 return key(getFirstEntry());
282 }
283
284 /**
285 * @throws NoSuchElementException {@inheritDoc}
286 */
287 public K lastKey() {
288 return key(getLastEntry());
289 }
290
291 /**
292 * Copies all of the mappings from the specified map to this map.
293 * These mappings replace any mappings that this map had for any
294 * of the keys currently in the specified map.
295 *
296 * @param map mappings to be stored in this map
297 * @throws ClassCastException if the class of a key or value in
298 * the specified map prevents it from being stored in this map
299 * @throws NullPointerException if the specified map is null or
300 * the specified map contains a null key and this map does not
301 * permit null keys
302 */
303 public void putAll(Map<? extends K, ? extends V> map) {
304 int mapSize = map.size();
305 if (size==0 && mapSize!=0 && map instanceof SortedMap) {
306 Comparator c = ((SortedMap)map).comparator();
307 if (c == comparator || (c != null && c.equals(comparator))) {
308 ++modCount;
309 try {
310 buildFromSorted(mapSize, map.entrySet().iterator(),
311 null, null);
312 } catch (java.io.IOException cannotHappen) {
313 } catch (ClassNotFoundException cannotHappen) {
314 }
315 return;
316 }
317 }
318 super.putAll(map);
319 }
320
321 /**
322 * Returns this map's entry for the given key, or <tt>null</tt> if the map
323 * does not contain an entry for the key.
324 *
325 * @return this map's entry for the given key, or <tt>null</tt> if the map
326 * does not contain an entry for the key
327 * @throws ClassCastException if the specified key cannot be compared
328 * with the keys currently in the map
329 * @throws NullPointerException if the specified key is null
330 * and this map uses natural ordering, or its comparator
331 * does not permit null keys
332 */
333 private Entry<K,V> getEntry(Object key) {
334 // Offload comparator-based version for sake of performance
335 if (comparator != null)
336 return getEntryUsingComparator(key);
337 Comparable<? super K> k = (Comparable<? super K>) key;
338 Entry<K,V> p = root;
339 while (p != null) {
340 int cmp = k.compareTo(p.key);
341 if (cmp < 0)
342 p = p.left;
343 else if (cmp > 0)
344 p = p.right;
345 else
346 return p;
347 }
348 return null;
349 }
350
351 /**
352 * Version of getEntry using comparator. Split off from getEntry
353 * for performance. (This is not worth doing for most methods,
354 * that are less dependent on comparator performance, but is
355 * worthwhile here.)
356 */
357 private Entry<K,V> getEntryUsingComparator(Object key) {
358 K k = (K) key;
359 Comparator<? super K> cpr = comparator;
360 Entry<K,V> p = root;
361 while (p != null) {
362 int cmp = cpr.compare(k, p.key);
363 if (cmp < 0)
364 p = p.left;
365 else if (cmp > 0)
366 p = p.right;
367 else
368 return p;
369 }
370 return null;
371 }
372
373 /**
374 * Gets the entry corresponding to the specified key; if no such entry
375 * exists, returns the entry for the least key greater than the specified
376 * key; if no such entry exists (i.e., the greatest key in the Tree is less
377 * than the specified key), returns <tt>null</tt>.
378 */
379 private Entry<K,V> getCeilingEntry(K key) {
380 Entry<K,V> p = root;
381 if (p==null)
382 return null;
383
384 while (true) {
385 int cmp = compare(key, p.key);
386 if (cmp < 0) {
387 if (p.left != null)
388 p = p.left;
389 else
390 return p;
391 } else if (cmp > 0) {
392 if (p.right != null) {
393 p = p.right;
394 } else {
395 Entry<K,V> parent = p.parent;
396 Entry<K,V> ch = p;
397 while (parent != null && ch == parent.right) {
398 ch = parent;
399 parent = parent.parent;
400 }
401 return parent;
402 }
403 } else
404 return p;
405 }
406 }
407
408 /**
409 * Gets the entry corresponding to the specified key; if no such entry
410 * exists, returns the entry for the greatest key less than the specified
411 * key; if no such entry exists, returns <tt>null</tt>.
412 */
413 private Entry<K,V> getFloorEntry(K key) {
414 Entry<K,V> p = root;
415 if (p==null)
416 return null;
417
418 while (true) {
419 int cmp = compare(key, p.key);
420 if (cmp > 0) {
421 if (p.right != null)
422 p = p.right;
423 else
424 return p;
425 } else if (cmp < 0) {
426 if (p.left != null) {
427 p = p.left;
428 } else {
429 Entry<K,V> parent = p.parent;
430 Entry<K,V> ch = p;
431 while (parent != null && ch == parent.left) {
432 ch = parent;
433 parent = parent.parent;
434 }
435 return parent;
436 }
437 } else
438 return p;
439
440 }
441 }
442
443 /**
444 * Gets the entry for the least key greater than the specified
445 * key; if no such entry exists, returns the entry for the least
446 * key greater than the specified key; if no such entry exists
447 * returns <tt>null</tt>.
448 */
449 private Entry<K,V> getHigherEntry(K key) {
450 Entry<K,V> p = root;
451 if (p==null)
452 return null;
453
454 while (true) {
455 int cmp = compare(key, p.key);
456 if (cmp < 0) {
457 if (p.left != null)
458 p = p.left;
459 else
460 return p;
461 } else {
462 if (p.right != null) {
463 p = p.right;
464 } else {
465 Entry<K,V> parent = p.parent;
466 Entry<K,V> ch = p;
467 while (parent != null && ch == parent.right) {
468 ch = parent;
469 parent = parent.parent;
470 }
471 return parent;
472 }
473 }
474 }
475 }
476
477 /**
478 * Returns the entry for the greatest key less than the specified key; if
479 * no such entry exists (i.e., the least key in the Tree is greater than
480 * the specified key), returns <tt>null</tt>.
481 */
482 private Entry<K,V> getLowerEntry(K key) {
483 Entry<K,V> p = root;
484 if (p==null)
485 return null;
486
487 while (true) {
488 int cmp = compare(key, p.key);
489 if (cmp > 0) {
490 if (p.right != null)
491 p = p.right;
492 else
493 return p;
494 } else {
495 if (p.left != null) {
496 p = p.left;
497 } else {
498 Entry<K,V> parent = p.parent;
499 Entry<K,V> ch = p;
500 while (parent != null && ch == parent.left) {
501 ch = parent;
502 parent = parent.parent;
503 }
504 return parent;
505 }
506 }
507 }
508 }
509
510 /**
511 * Returns the key corresponding to the specified Entry.
512 * @throws NoSuchElementException if the Entry is null
513 */
514 private static <K> K key(Entry<K,?> e) {
515 if (e==null)
516 throw new NoSuchElementException();
517 return e.key;
518 }
519
520 /**
521 * Associates the specified value with the specified key in this map.
522 * If the map previously contained a mapping for this key, the old
523 * value is replaced.
524 *
525 * @param key key with which the specified value is to be associated
526 * @param value value to be associated with the specified key
527 *
528 * @return the previous value associated with <tt>key</tt>, or
529 * <tt>null</tt> if there was no mapping for <tt>key</tt>.
530 * (A <tt>null</tt> return can also indicate that the map
531 * previously associated <tt>null</tt> with <tt>key</tt>.)
532 * @throws ClassCastException if the specified key cannot be compared
533 * with the keys currently in the map
534 * @throws NullPointerException if the specified key is null
535 * and this map uses natural ordering, or its comparator
536 * does not permit null keys
537 */
538 public V put(K key, V value) {
539 Entry<K,V> t = root;
540
541 if (t == null) {
542 if (key == null) {
543 if (comparator == null)
544 throw new NullPointerException();
545 comparator.compare(key, key);
546 }
547 incrementSize();
548 root = new Entry<K,V>(key, value, null);
549 return null;
550 }
551
552 while (true) {
553 int cmp = compare(key, t.key);
554 if (cmp == 0) {
555 return t.setValue(value);
556 } else if (cmp < 0) {
557 if (t.left != null) {
558 t = t.left;
559 } else {
560 incrementSize();
561 t.left = new Entry<K,V>(key, value, t);
562 fixAfterInsertion(t.left);
563 return null;
564 }
565 } else { // cmp > 0
566 if (t.right != null) {
567 t = t.right;
568 } else {
569 incrementSize();
570 t.right = new Entry<K,V>(key, value, t);
571 fixAfterInsertion(t.right);
572 return null;
573 }
574 }
575 }
576 }
577
578 /**
579 * Removes the mapping for this key from this TreeMap if present.
580 *
581 * @param key key for which mapping should be removed
582 * @return the previous value associated with <tt>key</tt>, or
583 * <tt>null</tt> if there was no mapping for <tt>key</tt>.
584 * (A <tt>null</tt> return can also indicate that the map
585 * previously associated <tt>null</tt> with <tt>key</tt>.)
586 * @throws ClassCastException if the specified key cannot be compared
587 * with the keys currently in the map
588 * @throws NullPointerException if the specified key is null
589 * and this map uses natural ordering, or its comparator
590 * does not permit null keys
591 */
592 public V remove(Object key) {
593 Entry<K,V> p = getEntry(key);
594 if (p == null)
595 return null;
596
597 V oldValue = p.value;
598 deleteEntry(p);
599 return oldValue;
600 }
601
602 /**
603 * Removes all of the mappings from this map.
604 * The map will be empty after this call returns.
605 */
606 public void clear() {
607 modCount++;
608 size = 0;
609 root = null;
610 }
611
612 /**
613 * Returns a shallow copy of this <tt>TreeMap</tt> instance. (The keys and
614 * values themselves are not cloned.)
615 *
616 * @return a shallow copy of this map
617 */
618 public Object clone() {
619 TreeMap<K,V> clone = null;
620 try {
621 clone = (TreeMap<K,V>) super.clone();
622 } catch (CloneNotSupportedException e) {
623 throw new InternalError();
624 }
625
626 // Put clone into "virgin" state (except for comparator)
627 clone.root = null;
628 clone.size = 0;
629 clone.modCount = 0;
630 clone.entrySet = null;
631 clone.descendingEntrySet = null;
632 clone.descendingKeySet = null;
633
634 // Initialize clone with our mappings
635 try {
636 clone.buildFromSorted(size, entrySet().iterator(), null, null);
637 } catch (java.io.IOException cannotHappen) {
638 } catch (ClassNotFoundException cannotHappen) {
639 }
640
641 return clone;
642 }
643
644 // NavigableMap API methods
645
646 public Map.Entry<K,V> firstEntry() {
647 Entry<K,V> e = getFirstEntry();
648 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
649 }
650
651 public Map.Entry<K,V> lastEntry() {
652 Entry<K,V> e = getLastEntry();
653 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
654 }
655
656 public Map.Entry<K,V> pollFirstEntry() {
657 Entry<K,V> p = getFirstEntry();
658 if (p == null)
659 return null;
660 Map.Entry result = new AbstractMap.SimpleImmutableEntry(p);
661 deleteEntry(p);
662 return result;
663 }
664
665 public Map.Entry<K,V> pollLastEntry() {
666 Entry<K,V> p = getLastEntry();
667 if (p == null)
668 return null;
669 Map.Entry result = new AbstractMap.SimpleImmutableEntry(p);
670 deleteEntry(p);
671 return result;
672 }
673
674 /**
675 * @throws ClassCastException {@inheritDoc}
676 * @throws NullPointerException if the specified key is null
677 * and this map uses natural ordering, or its comparator
678 * does not permit null keys
679 */
680 public Map.Entry<K,V> lowerEntry(K key) {
681 Entry<K,V> e = getLowerEntry(key);
682 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
683 }
684
685 /**
686 * @throws ClassCastException {@inheritDoc}
687 * @throws NullPointerException if the specified key is null
688 * and this map uses natural ordering, or its comparator
689 * does not permit null keys
690 */
691 public K lowerKey(K key) {
692 Entry<K,V> e = getLowerEntry(key);
693 return (e == null)? null : e.key;
694 }
695
696 /**
697 * @throws ClassCastException {@inheritDoc}
698 * @throws NullPointerException if the specified key is null
699 * and this map uses natural ordering, or its comparator
700 * does not permit null keys
701 */
702 public Map.Entry<K,V> floorEntry(K key) {
703 Entry<K,V> e = getFloorEntry(key);
704 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
705 }
706
707 /**
708 * @throws ClassCastException {@inheritDoc}
709 * @throws NullPointerException if the specified key is null
710 * and this map uses natural ordering, or its comparator
711 * does not permit null keys
712 */
713 public K floorKey(K key) {
714 Entry<K,V> e = getFloorEntry(key);
715 return (e == null)? null : e.key;
716 }
717
718 /**
719 * @throws ClassCastException {@inheritDoc}
720 * @throws NullPointerException if the specified key is null
721 * and this map uses natural ordering, or its comparator
722 * does not permit null keys
723 */
724 public Map.Entry<K,V> ceilingEntry(K key) {
725 Entry<K,V> e = getCeilingEntry(key);
726 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
727 }
728
729 /**
730 * @throws ClassCastException {@inheritDoc}
731 * @throws NullPointerException if the specified key is null
732 * and this map uses natural ordering, or its comparator
733 * does not permit null keys
734 */
735 public K ceilingKey(K key) {
736 Entry<K,V> e = getCeilingEntry(key);
737 return (e == null)? null : e.key;
738 }
739
740 /**
741 * @throws ClassCastException {@inheritDoc}
742 * @throws NullPointerException if the specified key is null
743 * and this map uses natural ordering, or its comparator
744 * does not permit null keys
745 */
746 public Map.Entry<K,V> higherEntry(K key) {
747 Entry<K,V> e = getHigherEntry(key);
748 return (e == null)? null : new AbstractMap.SimpleImmutableEntry(e);
749 }
750
751 /**
752 * @throws ClassCastException {@inheritDoc}
753 * @throws NullPointerException if the specified key is null
754 * and this map uses natural ordering, or its comparator
755 * does not permit null keys
756 */
757 public K higherKey(K key) {
758 Entry<K,V> e = getHigherEntry(key);
759 return (e == null)? null : e.key;
760 }
761
762 // Views
763
764 /**
765 * Fields initialized to contain an instance of the entry set view
766 * the first time this view is requested. Views are stateless, so
767 * there's no reason to create more than one.
768 */
769 private transient Set<Map.Entry<K,V>> entrySet = null;
770 private transient Set<Map.Entry<K,V>> descendingEntrySet = null;
771 private transient Set<K> descendingKeySet = null;
772
773 /**
774 * Returns a {@link Set} view of the keys contained in this map.
775 * The set's iterator returns the keys in ascending order.
776 * The set is backed by the map, so changes to the map are
777 * reflected in the set, and vice-versa. If the map is modified
778 * while an iteration over the set is in progress (except through
779 * the iterator's own <tt>remove</tt> operation), the results of
780 * the iteration are undefined. The set supports element removal,
781 * which removes the corresponding mapping from the map, via the
782 * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
783 * <tt>removeAll</tt> <tt>retainAll</tt>, and <tt>clear</tt>
784 * operations. It does not support the add or <tt>addAll</tt>
785 * operations.
786 */
787 public Set<K> keySet() {
788 Set<K> ks = keySet;
789 return (ks != null) ? ks : (keySet = new KeySet());
790 }
791
792 class KeySet extends AbstractSet<K> {
793 public Iterator<K> iterator() {
794 return new KeyIterator(getFirstEntry());
795 }
796
797 public int size() {
798 return TreeMap.this.size();
799 }
800
801 public boolean contains(Object o) {
802 return containsKey(o);
803 }
804
805 public boolean remove(Object o) {
806 int oldSize = size;
807 TreeMap.this.remove(o);
808 return size != oldSize;
809 }
810
811 public void clear() {
812 TreeMap.this.clear();
813 }
814 }
815
816 /**
817 * Returns a {@link Collection} view of the values contained in this map.
818 * The collection's iterator returns the values in ascending order
819 * of the corresponding keys.
820 * The collection is backed by the map, so changes to the map are
821 * reflected in the collection, and vice-versa. If the map is
822 * modified while an iteration over the collection is in progress
823 * (except through the iterator's own <tt>remove</tt> operation),
824 * the results of the iteration are undefined. The collection
825 * supports element removal, which removes the corresponding
826 * mapping from the map, via the <tt>Iterator.remove</tt>,
827 * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
828 * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
829 * support the add or <tt>addAll</tt> operations.
830 */
831 public Collection<V> values() {
832 Collection<V> vs = values;
833 return (vs != null) ? vs : (values = new Values());
834 }
835
836 class Values extends AbstractCollection<V> {
837 public Iterator<V> iterator() {
838 return new ValueIterator(getFirstEntry());
839 }
840
841 public int size() {
842 return TreeMap.this.size();
843 }
844
845 public boolean contains(Object o) {
846 for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
847 if (valEquals(e.getValue(), o))
848 return true;
849 return false;
850 }
851
852 public boolean remove(Object o) {
853 for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
854 if (valEquals(e.getValue(), o)) {
855 deleteEntry(e);
856 return true;
857 }
858 }
859 return false;
860 }
861
862 public void clear() {
863 TreeMap.this.clear();
864 }
865 }
866
867 /**
868 * Returns a {@link Set} view of the mappings contained in this map.
869 * The set's iterator returns the entries in ascending key order.
870 * The set is backed by the map, so changes to the map are
871 * reflected in the set, and vice-versa. If the map is modified
872 * while an iteration over the set is in progress (except through
873 * the iterator's own <tt>remove</tt> operation, or through the
874 * <tt>setValue</tt> operation on a map entry returned by the
875 * iterator) the results of the iteration are undefined. The set
876 * supports element removal, which removes the corresponding
877 * mapping from the map, via the <tt>Iterator.remove</tt>,
878 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
879 * <tt>clear</tt> operations. It does not support the
880 * <tt>add</tt> or <tt>addAll</tt> operations.
881 */
882 public Set<Map.Entry<K,V>> entrySet() {
883 Set<Map.Entry<K,V>> es = entrySet;
884 return (es != null) ? es : (entrySet = new EntrySet());
885 }
886
887 class EntrySet extends AbstractSet<Map.Entry<K,V>> {
888 public Iterator<Map.Entry<K,V>> iterator() {
889 return new EntryIterator(getFirstEntry());
890 }
891
892 public boolean contains(Object o) {
893 if (!(o instanceof Map.Entry))
894 return false;
895 Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
896 V value = entry.getValue();
897 Entry<K,V> p = getEntry(entry.getKey());
898 return p != null && valEquals(p.getValue(), value);
899 }
900
901 public boolean remove(Object o) {
902 if (!(o instanceof Map.Entry))
903 return false;
904 Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
905 V value = entry.getValue();
906 Entry<K,V> p = getEntry(entry.getKey());
907 if (p != null && valEquals(p.getValue(), value)) {
908 deleteEntry(p);
909 return true;
910 }
911 return false;
912 }
913
914 public int size() {
915 return TreeMap.this.size();
916 }
917
918 public void clear() {
919 TreeMap.this.clear();
920 }
921 }
922
923 public Set<Map.Entry<K,V>> descendingEntrySet() {
924 Set<Map.Entry<K,V>> es = descendingEntrySet;
925 return (es != null) ? es : (descendingEntrySet = new DescendingEntrySet());
926 }
927
928 class DescendingEntrySet extends EntrySet {
929 public Iterator<Map.Entry<K,V>> iterator() {
930 return new DescendingEntryIterator(getLastEntry());
931 }
932 }
933
934 public Set<K> descendingKeySet() {
935 Set<K> ks = descendingKeySet;
936 return (ks != null) ? ks : (descendingKeySet = new DescendingKeySet());
937 }
938
939 class DescendingKeySet extends KeySet {
940 public Iterator<K> iterator() {
941 return new DescendingKeyIterator(getLastEntry());
942 }
943 }
944
945 /**
946 * @throws ClassCastException {@inheritDoc}
947 * @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
948 * null and this map uses natural ordering, or its comparator
949 * does not permit null keys
950 * @throws IllegalArgumentException {@inheritDoc}
951 */
952 public NavigableMap<K,V> navigableSubMap(K fromKey, K toKey) {
953 return new SubMap(fromKey, toKey);
954 }
955
956 /**
957 * @throws ClassCastException {@inheritDoc}
958 * @throws NullPointerException if <tt>toKey</tt> is null
959 * and this map uses natural ordering, or its comparator
960 * does not permit null keys
961 * @throws IllegalArgumentException {@inheritDoc}
962 */
963 public NavigableMap<K,V> navigableHeadMap(K toKey) {
964 return new SubMap(toKey, true);
965 }
966
967 /**
968 * @throws ClassCastException {@inheritDoc}
969 * @throws NullPointerException if <tt>fromKey</tt> is null
970 * and this map uses natural ordering, or its comparator
971 * does not permit null keys
972 * @throws IllegalArgumentException {@inheritDoc}
973 */
974 public NavigableMap<K,V> navigableTailMap(K fromKey) {
975 return new SubMap(fromKey, false);
976 }
977
978 /**
979 * Equivalent to {@link #navigableSubMap} but with a return type
980 * conforming to the <tt>SortedMap</tt> interface.
981 *
982 * <p>{@inheritDoc}
983 *
984 * @throws ClassCastException {@inheritDoc}
985 * @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
986 * null and this map uses natural ordering, or its comparator
987 * does not permit null keys
988 * @throws IllegalArgumentException {@inheritDoc}
989 */
990 public SortedMap<K,V> subMap(K fromKey, K toKey) {
991 return new SubMap(fromKey, toKey);
992 }
993
994 /**
995 * Equivalent to {@link #navigableHeadMap} but with a return type
996 * conforming to the <tt>SortedMap</tt> interface.
997 *
998 * <p>{@inheritDoc}
999 *
1000 * @throws ClassCastException {@inheritDoc}
1001 * @throws NullPointerException if <tt>toKey</tt> is null
1002 * and this map uses natural ordering, or its comparator
1003 * does not permit null keys
1004 * @throws IllegalArgumentException {@inheritDoc}
1005 */
1006 public SortedMap<K,V> headMap(K toKey) {
1007 return new SubMap(toKey, true);
1008 }
1009
1010 /**
1011 * Equivalent to {@link #navigableTailMap} but with a return type
1012 * conforming to the <tt>SortedMap</tt> interface.
1013 *
1014 * <p>{@inheritDoc}
1015 *
1016 * @throws ClassCastException {@inheritDoc}
1017 * @throws NullPointerException if <tt>fromKey</tt> is null
1018 * and this map uses natural ordering, or its comparator
1019 * does not permit null keys
1020 * @throws IllegalArgumentException {@inheritDoc}
1021 */
1022 public SortedMap<K,V> tailMap(K fromKey) {
1023 return new SubMap(fromKey, false);
1024 }
1025
1026 private class SubMap
1027 extends AbstractMap<K,V>
1028 implements NavigableMap<K,V>, java.io.Serializable {
1029 private static final long serialVersionUID = -6520786458950516097L;
1030
1031 /**
1032 * fromKey is significant only if fromStart is false. Similarly,
1033 * toKey is significant only if toStart is false.
1034 */
1035 private boolean fromStart = false, toEnd = false;
1036 private K fromKey, toKey;
1037
1038 SubMap(K fromKey, K toKey) {
1039 if (compare(fromKey, toKey) > 0)
1040 throw new IllegalArgumentException("fromKey > toKey");
1041 this.fromKey = fromKey;
1042 this.toKey = toKey;
1043 }
1044
1045 SubMap(K key, boolean headMap) {
1046 compare(key, key); // Type-check key
1047
1048 if (headMap) {
1049 fromStart = true;
1050 toKey = key;
1051 } else {
1052 toEnd = true;
1053 fromKey = key;
1054 }
1055 }
1056
1057 SubMap(boolean fromStart, K fromKey, boolean toEnd, K toKey) {
1058 this.fromStart = fromStart;
1059 this.fromKey= fromKey;
1060 this.toEnd = toEnd;
1061 this.toKey = toKey;
1062 }
1063
1064 public boolean isEmpty() {
1065 return entrySet().isEmpty();
1066 }
1067
1068 public boolean containsKey(Object key) {
1069 return inRange((K) key) && TreeMap.this.containsKey(key);
1070 }
1071
1072 public V get(Object key) {
1073 if (!inRange((K) key))
1074 return null;
1075 return TreeMap.this.get(key);
1076 }
1077
1078 public V put(K key, V value) {
1079 if (!inRange(key))
1080 throw new IllegalArgumentException("key out of range");
1081 return TreeMap.this.put(key, value);
1082 }
1083
1084 public V remove(Object key) {
1085 if (!inRange((K) key))
1086 return null;
1087 return TreeMap.this.remove(key);
1088 }
1089
1090 public Comparator<? super K> comparator() {
1091 return comparator;
1092 }
1093
1094 public K firstKey() {
1095 TreeMap.Entry<K,V> e = fromStart ? getFirstEntry() : getCeilingEntry(fromKey);
1096 K first = key(e);
1097 if (!toEnd && compare(first, toKey) >= 0)
1098 throw new NoSuchElementException();
1099 return first;
1100 }
1101
1102 public K lastKey() {
1103 TreeMap.Entry<K,V> e = toEnd ? getLastEntry() : getLowerEntry(toKey);
1104 K last = key(e);
1105 if (!fromStart && compare(last, fromKey) < 0)
1106 throw new NoSuchElementException();
1107 return last;
1108 }
1109
1110 public Map.Entry<K,V> firstEntry() {
1111 TreeMap.Entry<K,V> e = fromStart ?
1112 getFirstEntry() : getCeilingEntry(fromKey);
1113 if (e == null || (!toEnd && compare(e.key, toKey) >= 0))
1114 return null;
1115 return e;
1116 }
1117
1118 public Map.Entry<K,V> lastEntry() {
1119 TreeMap.Entry<K,V> e = toEnd ?
1120 getLastEntry() : getLowerEntry(toKey);
1121 if (e == null || (!fromStart && compare(e.key, fromKey) < 0))
1122 return null;
1123 return e;
1124 }
1125
1126 public Map.Entry<K,V> pollFirstEntry() {
1127 TreeMap.Entry<K,V> e = fromStart ?
1128 getFirstEntry() : getCeilingEntry(fromKey);
1129 if (e == null || (!toEnd && compare(e.key, toKey) >= 0))
1130 return null;
1131 Map.Entry result = new AbstractMap.SimpleImmutableEntry(e);
1132 deleteEntry(e);
1133 return result;
1134 }
1135
1136 public Map.Entry<K,V> pollLastEntry() {
1137 TreeMap.Entry<K,V> e = toEnd ?
1138 getLastEntry() : getLowerEntry(toKey);
1139 if (e == null || (!fromStart && compare(e.key, fromKey) < 0))
1140 return null;
1141 Map.Entry result = new AbstractMap.SimpleImmutableEntry(e);
1142 deleteEntry(e);
1143 return result;
1144 }
1145
1146 private TreeMap.Entry<K,V> subceiling(K key) {
1147 TreeMap.Entry<K,V> e = (!fromStart && compare(key, fromKey) < 0)?
1148 getCeilingEntry(fromKey) : getCeilingEntry(key);
1149 if (e == null || (!toEnd && compare(e.key, toKey) >= 0))
1150 return null;
1151 return e;
1152 }
1153
1154 public Map.Entry<K,V> ceilingEntry(K key) {
1155 TreeMap.Entry<K,V> e = subceiling(key);
1156 return e == null? null : new AbstractMap.SimpleImmutableEntry(e);
1157 }
1158
1159 public K ceilingKey(K key) {
1160 TreeMap.Entry<K,V> e = subceiling(key);
1161 return e == null? null : e.key;
1162 }
1163
1164
1165 private TreeMap.Entry<K,V> subhigher(K key) {
1166 TreeMap.Entry<K,V> e = (!fromStart && compare(key, fromKey) < 0)?
1167 getCeilingEntry(fromKey) : getHigherEntry(key);
1168 if (e == null || (!toEnd && compare(e.key, toKey) >= 0))
1169 return null;
1170 return e;
1171 }
1172
1173 public Map.Entry<K,V> higherEntry(K key) {
1174 TreeMap.Entry<K,V> e = subhigher(key);
1175 return e == null? null : new AbstractMap.SimpleImmutableEntry(e);
1176 }
1177
1178 public K higherKey(K key) {
1179 TreeMap.Entry<K,V> e = subhigher(key);
1180 return e == null? null : e.key;
1181 }
1182
1183 private TreeMap.Entry<K,V> subfloor(K key) {
1184 TreeMap.Entry<K,V> e = (!toEnd && compare(key, toKey) >= 0)?
1185 getLowerEntry(toKey) : getFloorEntry(key);
1186 if (e == null || (!fromStart && compare(e.key, fromKey) < 0))
1187 return null;
1188 return e;
1189 }
1190
1191 public Map.Entry<K,V> floorEntry(K key) {
1192 TreeMap.Entry<K,V> e = subfloor(key);
1193 return e == null? null : new AbstractMap.SimpleImmutableEntry(e);
1194 }
1195
1196 public K floorKey(K key) {
1197 TreeMap.Entry<K,V> e = subfloor(key);
1198 return e == null? null : e.key;
1199 }
1200
1201 private TreeMap.Entry<K,V> sublower(K key) {
1202 TreeMap.Entry<K,V> e = (!toEnd && compare(key, toKey) >= 0)?
1203 getLowerEntry(toKey) : getLowerEntry(key);
1204 if (e == null || (!fromStart && compare(e.key, fromKey) < 0))
1205 return null;
1206 return e;
1207 }
1208
1209 public Map.Entry<K,V> lowerEntry(K key) {
1210 TreeMap.Entry<K,V> e = sublower(key);
1211 return e == null? null : new AbstractMap.SimpleImmutableEntry(e);
1212 }
1213
1214 public K lowerKey(K key) {
1215 TreeMap.Entry<K,V> e = sublower(key);
1216 return e == null? null : e.key;
1217 }
1218
1219 private transient Set<Map.Entry<K,V>> entrySet = null;
1220
1221 public Set<Map.Entry<K,V>> entrySet() {
1222 Set<Map.Entry<K,V>> es = entrySet;
1223 return (es != null)? es : (entrySet = new EntrySetView());
1224 }
1225
1226 private class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
1227 private transient int size = -1, sizeModCount;
1228
1229 public int size() {
1230 if (size == -1 || sizeModCount != TreeMap.this.modCount) {
1231 size = 0; sizeModCount = TreeMap.this.modCount;
1232 Iterator i = iterator();
1233 while (i.hasNext()) {
1234 size++;
1235 i.next();
1236 }
1237 }
1238 return size;
1239 }
1240
1241 public boolean isEmpty() {
1242 return !iterator().hasNext();
1243 }
1244
1245 public boolean contains(Object o) {
1246 if (!(o instanceof Map.Entry))
1247 return false;
1248 Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
1249 K key = entry.getKey();
1250 if (!inRange(key))
1251 return false;
1252 TreeMap.Entry node = getEntry(key);
1253 return node != null &&
1254 valEquals(node.getValue(), entry.getValue());
1255 }
1256
1257 public boolean remove(Object o) {
1258 if (!(o instanceof Map.Entry))
1259 return false;
1260 Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
1261 K key = entry.getKey();
1262 if (!inRange(key))
1263 return false;
1264 TreeMap.Entry<K,V> node = getEntry(key);
1265 if (node!=null && valEquals(node.getValue(),entry.getValue())){
1266 deleteEntry(node);
1267 return true;
1268 }
1269 return false;
1270 }
1271
1272 public Iterator<Map.Entry<K,V>> iterator() {
1273 return new SubMapEntryIterator(
1274 (fromStart ? getFirstEntry() : getCeilingEntry(fromKey)),
1275 (toEnd ? null : getCeilingEntry(toKey)));
1276 }
1277 }
1278
1279 private transient Set<Map.Entry<K,V>> descendingEntrySetView = null;
1280 private transient Set<K> descendingKeySetView = null;
1281
1282 public Set<Map.Entry<K,V>> descendingEntrySet() {
1283 Set<Map.Entry<K,V>> es = descendingEntrySetView;
1284 return (es != null) ? es :
1285 (descendingEntrySetView = new DescendingEntrySetView());
1286 }
1287
1288 public Set<K> descendingKeySet() {
1289 Set<K> ks = descendingKeySetView;
1290 return (ks != null) ? ks :
1291 (descendingKeySetView = new DescendingKeySetView());
1292 }
1293
1294 private class DescendingEntrySetView extends EntrySetView {
1295 public Iterator<Map.Entry<K,V>> iterator() {
1296 return new DescendingSubMapEntryIterator
1297 ((toEnd ? getLastEntry() : getLowerEntry(toKey)),
1298 (fromStart ? null : getLowerEntry(fromKey)));
1299 }
1300 }
1301
1302 private class DescendingKeySetView extends AbstractSet<K> {
1303 public Iterator<K> iterator() {
1304 return new Iterator<K>() {
1305 private Iterator<Entry<K,V>> i = descendingEntrySet().iterator();
1306
1307 public boolean hasNext() { return i.hasNext(); }
1308 public K next() { return i.next().getKey(); }
1309 public void remove() { i.remove(); }
1310 };
1311 }
1312
1313 public int size() {
1314 return SubMap.this.size();
1315 }
1316
1317 public boolean contains(Object k) {
1318 return SubMap.this.containsKey(k);
1319 }
1320 }
1321
1322 public NavigableMap<K,V> navigableSubMap(K fromKey, K toKey) {
1323 if (!inRange2(fromKey))
1324 throw new IllegalArgumentException("fromKey out of range");
1325 if (!inRange2(toKey))
1326 throw new IllegalArgumentException("toKey out of range");
1327 return new SubMap(fromKey, toKey);
1328 }
1329
1330 public NavigableMap<K,V> navigableHeadMap(K toKey) {
1331 if (!inRange2(toKey))
1332 throw new IllegalArgumentException("toKey out of range");
1333 return new SubMap(fromStart, fromKey, false, toKey);
1334 }
1335
1336 public NavigableMap<K,V> navigableTailMap(K fromKey) {
1337 if (!inRange2(fromKey))
1338 throw new IllegalArgumentException("fromKey out of range");
1339 return new SubMap(false, fromKey, toEnd, toKey);
1340 }
1341
1342 public SortedMap<K,V> subMap(K fromKey, K toKey) {
1343 return navigableSubMap(fromKey, toKey);
1344 }
1345
1346 public SortedMap<K,V> headMap(K toKey) {
1347 return navigableHeadMap(toKey);
1348 }
1349
1350 public SortedMap<K,V> tailMap(K fromKey) {
1351 return navigableTailMap(fromKey);
1352 }
1353
1354 private boolean inRange(K key) {
1355 return (fromStart || compare(key, fromKey) >= 0) &&
1356 (toEnd || compare(key, toKey) < 0);
1357 }
1358
1359 // This form allows the high endpoint (as well as all legit keys)
1360 private boolean inRange2(K key) {
1361 return (fromStart || compare(key, fromKey) >= 0) &&
1362 (toEnd || compare(key, toKey) <= 0);
1363 }
1364 }
1365
1366 /**
1367 * TreeMap Iterator.
1368 */
1369 abstract class PrivateEntryIterator<T> implements Iterator<T> {
1370 int expectedModCount = TreeMap.this.modCount;
1371 Entry<K,V> lastReturned = null;
1372 Entry<K,V> next;
1373
1374 PrivateEntryIterator(Entry<K,V> first) {
1375 next = first;
1376 }
1377
1378 public boolean hasNext() {
1379 return next != null;
1380 }
1381
1382 Entry<K,V> nextEntry() {
1383 if (next == null)
1384 throw new NoSuchElementException();
1385 if (modCount != expectedModCount)
1386 throw new ConcurrentModificationException();
1387 lastReturned = next;
1388 next = successor(next);
1389 return lastReturned;
1390 }
1391
1392 public void remove() {
1393 if (lastReturned == null)
1394 throw new IllegalStateException();
1395 if (modCount != expectedModCount)
1396 throw new ConcurrentModificationException();
1397 if (lastReturned.left != null && lastReturned.right != null)
1398 next = lastReturned;
1399 deleteEntry(lastReturned);
1400 expectedModCount++;
1401 lastReturned = null;
1402 }
1403 }
1404
1405 class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
1406 EntryIterator(Entry<K,V> first) {
1407 super(first);
1408 }
1409 public Map.Entry<K,V> next() {
1410 return nextEntry();
1411 }
1412 }
1413
1414 class KeyIterator extends PrivateEntryIterator<K> {
1415 KeyIterator(Entry<K,V> first) {
1416 super(first);
1417 }
1418 public K next() {
1419 return nextEntry().key;
1420 }
1421 }
1422
1423 class ValueIterator extends PrivateEntryIterator<V> {
1424 ValueIterator(Entry<K,V> first) {
1425 super(first);
1426 }
1427 public V next() {
1428 return nextEntry().value;
1429 }
1430 }
1431
1432 class SubMapEntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
1433 private final K firstExcludedKey;
1434
1435 SubMapEntryIterator(Entry<K,V> first, Entry<K,V> firstExcluded) {
1436 super(first);
1437 firstExcludedKey = (firstExcluded == null
1438 ? null
1439 : firstExcluded.key);
1440 }
1441
1442 public boolean hasNext() {
1443 return next != null && next.key != firstExcludedKey;
1444 }
1445
1446 public Map.Entry<K,V> next() {
1447 if (next == null || next.key == firstExcludedKey)
1448 throw new NoSuchElementException();
1449 return nextEntry();
1450 }
1451 }
1452
1453 /**
1454 * Base for Descending Iterators.
1455 */
1456 abstract class DescendingPrivateEntryIterator<T> extends PrivateEntryIterator<T> {
1457 DescendingPrivateEntryIterator(Entry<K,V> first) {
1458 super(first);
1459 }
1460
1461 Entry<K,V> nextEntry() {
1462 if (next == null)
1463 throw new NoSuchElementException();
1464 if (modCount != expectedModCount)
1465 throw new ConcurrentModificationException();
1466 lastReturned = next;
1467 next = predecessor(next);
1468 return lastReturned;
1469 }
1470 }
1471
1472 class DescendingEntryIterator extends DescendingPrivateEntryIterator<Map.Entry<K,V>> {
1473 DescendingEntryIterator(Entry<K,V> first) {
1474 super(first);
1475 }
1476 public Map.Entry<K,V> next() {
1477 return nextEntry();
1478 }
1479 }
1480
1481 class DescendingKeyIterator extends DescendingPrivateEntryIterator<K> {
1482 DescendingKeyIterator(Entry<K,V> first) {
1483 super(first);
1484 }
1485 public K next() {
1486 return nextEntry().key;
1487 }
1488 }
1489
1490
1491 class DescendingSubMapEntryIterator extends DescendingPrivateEntryIterator<Map.Entry<K,V>> {
1492 private final K lastExcludedKey;
1493
1494 DescendingSubMapEntryIterator(Entry<K,V> last, Entry<K,V> lastExcluded) {
1495 super(last);
1496 lastExcludedKey = (lastExcluded == null
1497 ? null
1498 : lastExcluded.key);
1499 }
1500
1501 public boolean hasNext() {
1502 return next != null && next.key != lastExcludedKey;
1503 }
1504
1505 public Map.Entry<K,V> next() {
1506 if (next == null || next.key == lastExcludedKey)
1507 throw new NoSuchElementException();
1508 return nextEntry();
1509 }
1510
1511 }
1512
1513 /**
1514 * Compares two keys using the correct comparison method for this TreeMap.
1515 */
1516 private int compare(K k1, K k2) {
1517 return comparator==null ? ((Comparable<? super K>)k1).compareTo(k2)
1518 : comparator.compare(k1, k2);
1519 }
1520
1521 /**
1522 * Test two values for equality. Differs from o1.equals(o2) only in
1523 * that it copes with <tt>null</tt> o1 properly.
1524 */
1525 private static boolean valEquals(Object o1, Object o2) {
1526 return (o1==null ? o2==null : o1.equals(o2));
1527 }
1528
1529 private static final boolean RED = false;
1530 private static final boolean BLACK = true;
1531
1532 /**
1533 * Node in the Tree. Doubles as a means to pass key-value pairs back to
1534 * user (see Map.Entry).
1535 */
1536
1537 static class Entry<K,V> implements Map.Entry<K,V> {
1538 K key;
1539 V value;
1540 Entry<K,V> left = null;
1541 Entry<K,V> right = null;
1542 Entry<K,V> parent;
1543 boolean color = BLACK;
1544
1545 /**
1546 * Make a new cell with given key, value, and parent, and with
1547 * <tt>null</tt> child links, and BLACK color.
1548 */
1549 Entry(K key, V value, Entry<K,V> parent) {
1550 this.key = key;
1551 this.value = value;
1552 this.parent = parent;
1553 }
1554
1555 /**
1556 * Returns the key.
1557 *
1558 * @return the key
1559 */
1560 public K getKey() {
1561 return key;
1562 }
1563
1564 /**
1565 * Returns the value associated with the key.
1566 *
1567 * @return the value associated with the key
1568 */
1569 public V getValue() {
1570 return value;
1571 }
1572
1573 /**
1574 * Replaces the value currently associated with the key with the given
1575 * value.
1576 *
1577 * @return the value associated with the key before this method was
1578 * called
1579 */
1580 public V setValue(V value) {
1581 V oldValue = this.value;
1582 this.value = value;
1583 return oldValue;
1584 }
1585
1586 public boolean equals(Object o) {
1587 if (!(o instanceof Map.Entry))
1588 return false;
1589 Map.Entry e = (Map.Entry)o;
1590
1591 return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
1592 }
1593
1594 public int hashCode() {
1595 int keyHash = (key==null ? 0 : key.hashCode());
1596 int valueHash = (value==null ? 0 : value.hashCode());
1597 return keyHash ^ valueHash;
1598 }
1599
1600 public String toString() {
1601 return key + "=" + value;
1602 }
1603 }
1604
1605 /**
1606 * Returns the first Entry in the TreeMap (according to the TreeMap's
1607 * key-sort function). Returns null if the TreeMap is empty.
1608 */
1609 private Entry<K,V> getFirstEntry() {
1610 Entry<K,V> p = root;
1611 if (p != null)
1612 while (p.left != null)
1613 p = p.left;
1614 return p;
1615 }
1616
1617 /**
1618 * Returns the last Entry in the TreeMap (according to the TreeMap's
1619 * key-sort function). Returns null if the TreeMap is empty.
1620 */
1621 private Entry<K,V> getLastEntry() {
1622 Entry<K,V> p = root;
1623 if (p != null)
1624 while (p.right != null)
1625 p = p.right;
1626 return p;
1627 }
1628
1629 /**
1630 * Returns the successor of the specified Entry, or null if no such.
1631 */
1632 private Entry<K,V> successor(Entry<K,V> t) {
1633 if (t == null)
1634 return null;
1635 else if (t.right != null) {
1636 Entry<K,V> p = t.right;
1637 while (p.left != null)
1638 p = p.left;
1639 return p;
1640 } else {
1641 Entry<K,V> p = t.parent;
1642 Entry<K,V> ch = t;
1643 while (p != null && ch == p.right) {
1644 ch = p;
1645 p = p.parent;
1646 }
1647 return p;
1648 }
1649 }
1650
1651 /**
1652 * Returns the predecessor of the specified Entry, or null if no such.
1653 */
1654 private Entry<K,V> predecessor(Entry<K,V> t) {
1655 if (t == null)
1656 return null;
1657 else if (t.left != null) {
1658 Entry<K,V> p = t.left;
1659 while (p.right != null)
1660 p = p.right;
1661 return p;
1662 } else {
1663 Entry<K,V> p = t.parent;
1664 Entry<K,V> ch = t;
1665 while (p != null && ch == p.left) {
1666 ch = p;
1667 p = p.parent;
1668 }
1669 return p;
1670 }
1671 }
1672
1673 /**
1674 * Balancing operations.
1675 *
1676 * Implementations of rebalancings during insertion and deletion are
1677 * slightly different than the CLR version. Rather than using dummy
1678 * nilnodes, we use a set of accessors that deal properly with null. They
1679 * are used to avoid messiness surrounding nullness checks in the main
1680 * algorithms.
1681 */
1682
1683 private static <K,V> boolean colorOf(Entry<K,V> p) {
1684 return (p == null ? BLACK : p.color);
1685 }
1686
1687 private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) {
1688 return (p == null ? null: p.parent);
1689 }
1690
1691 private static <K,V> void setColor(Entry<K,V> p, boolean c) {
1692 if (p != null)
1693 p.color = c;
1694 }
1695
1696 private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
1697 return (p == null) ? null: p.left;
1698 }
1699
1700 private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) {
1701 return (p == null) ? null: p.right;
1702 }
1703
1704 /** From CLR **/
1705 private void rotateLeft(Entry<K,V> p) {
1706 Entry<K,V> r = p.right;
1707 p.right = r.left;
1708 if (r.left != null)
1709 r.left.parent = p;
1710 r.parent = p.parent;
1711 if (p.parent == null)
1712 root = r;
1713 else if (p.parent.left == p)
1714 p.parent.left = r;
1715 else
1716 p.parent.right = r;
1717 r.left = p;
1718 p.parent = r;
1719 }
1720
1721 /** From CLR **/
1722 private void rotateRight(Entry<K,V> p) {
1723 Entry<K,V> l = p.left;
1724 p.left = l.right;
1725 if (l.right != null) l.right.parent = p;
1726 l.parent = p.parent;
1727 if (p.parent == null)
1728 root = l;
1729 else if (p.parent.right == p)
1730 p.parent.right = l;
1731 else p.parent.left = l;
1732 l.right = p;
1733 p.parent = l;
1734 }
1735
1736
1737 /** From CLR **/
1738 private void fixAfterInsertion(Entry<K,V> x) {
1739 x.color = RED;
1740
1741 while (x != null && x != root && x.parent.color == RED) {
1742 if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
1743 Entry<K,V> y = rightOf(parentOf(parentOf(x)));
1744 if (colorOf(y) == RED) {
1745 setColor(parentOf(x), BLACK);
1746 setColor(y, BLACK);
1747 setColor(parentOf(parentOf(x)), RED);
1748 x = parentOf(parentOf(x));
1749 } else {
1750 if (x == rightOf(parentOf(x))) {
1751 x = parentOf(x);
1752 rotateLeft(x);
1753 }
1754 setColor(parentOf(x), BLACK);
1755 setColor(parentOf(parentOf(x)), RED);
1756 if (parentOf(parentOf(x)) != null)
1757 rotateRight(parentOf(parentOf(x)));
1758 }
1759 } else {
1760 Entry<K,V> y = leftOf(parentOf(parentOf(x)));
1761 if (colorOf(y) == RED) {
1762 setColor(parentOf(x), BLACK);
1763 setColor(y, BLACK);
1764 setColor(parentOf(parentOf(x)), RED);
1765 x = parentOf(parentOf(x));
1766 } else {
1767 if (x == leftOf(parentOf(x))) {
1768 x = parentOf(x);
1769 rotateRight(x);
1770 }
1771 setColor(parentOf(x), BLACK);
1772 setColor(parentOf(parentOf(x)), RED);
1773 if (parentOf(parentOf(x)) != null)
1774 rotateLeft(parentOf(parentOf(x)));
1775 }
1776 }
1777 }
1778 root.color = BLACK;
1779 }
1780
1781 /**
1782 * Delete node p, and then rebalance the tree.
1783 */
1784
1785 private void deleteEntry(Entry<K,V> p) {
1786 decrementSize();
1787
1788 // If strictly internal, copy successor's element to p and then make p
1789 // point to successor.
1790 if (p.left != null && p.right != null) {
1791 Entry<K,V> s = successor (p);
1792 p.key = s.key;
1793 p.value = s.value;
1794 p = s;
1795 } // p has 2 children
1796
1797 // Start fixup at replacement node, if it exists.
1798 Entry<K,V> replacement = (p.left != null ? p.left : p.right);
1799
1800 if (replacement != null) {
1801 // Link replacement to parent
1802 replacement.parent = p.parent;
1803 if (p.parent == null)
1804 root = replacement;
1805 else if (p == p.parent.left)
1806 p.parent.left = replacement;
1807 else
1808 p.parent.right = replacement;
1809
1810 // Null out links so they are OK to use by fixAfterDeletion.
1811 p.left = p.right = p.parent = null;
1812
1813 // Fix replacement
1814 if (p.color == BLACK)
1815 fixAfterDeletion(replacement);
1816 } else if (p.parent == null) { // return if we are the only node.
1817 root = null;
1818 } else { // No children. Use self as phantom replacement and unlink.
1819 if (p.color == BLACK)
1820 fixAfterDeletion(p);
1821
1822 if (p.parent != null) {
1823 if (p == p.parent.left)
1824 p.parent.left = null;
1825 else if (p == p.parent.right)
1826 p.parent.right = null;
1827 p.parent = null;
1828 }
1829 }
1830 }
1831
1832 /** From CLR **/
1833 private void fixAfterDeletion(Entry<K,V> x) {
1834 while (x != root && colorOf(x) == BLACK) {
1835 if (x == leftOf(parentOf(x))) {
1836 Entry<K,V> sib = rightOf(parentOf(x));
1837
1838 if (colorOf(sib) == RED) {
1839 setColor(sib, BLACK);
1840 setColor(parentOf(x), RED);
1841 rotateLeft(parentOf(x));
1842 sib = rightOf(parentOf(x));
1843 }
1844
1845 if (colorOf(leftOf(sib)) == BLACK &&
1846 colorOf(rightOf(sib)) == BLACK) {
1847 setColor(sib, RED);
1848 x = parentOf(x);
1849 } else {
1850 if (colorOf(rightOf(sib)) == BLACK) {
1851 setColor(leftOf(sib), BLACK);
1852 setColor(sib, RED);
1853 rotateRight(sib);
1854 sib = rightOf(parentOf(x));
1855 }
1856 setColor(sib, colorOf(parentOf(x)));
1857 setColor(parentOf(x), BLACK);
1858 setColor(rightOf(sib), BLACK);
1859 rotateLeft(parentOf(x));
1860 x = root;
1861 }
1862 } else { // symmetric
1863 Entry<K,V> sib = leftOf(parentOf(x));
1864
1865 if (colorOf(sib) == RED) {
1866 setColor(sib, BLACK);
1867 setColor(parentOf(x), RED);
1868 rotateRight(parentOf(x));
1869 sib = leftOf(parentOf(x));
1870 }
1871
1872 if (colorOf(rightOf(sib)) == BLACK &&
1873 colorOf(leftOf(sib)) == BLACK) {
1874 setColor(sib, RED);
1875 x = parentOf(x);
1876 } else {
1877 if (colorOf(leftOf(sib)) == BLACK) {
1878 setColor(rightOf(sib), BLACK);
1879 setColor(sib, RED);
1880 rotateLeft(sib);
1881 sib = leftOf(parentOf(x));
1882 }
1883 setColor(sib, colorOf(parentOf(x)));
1884 setColor(parentOf(x), BLACK);
1885 setColor(leftOf(sib), BLACK);
1886 rotateRight(parentOf(x));
1887 x = root;
1888 }
1889 }
1890 }
1891
1892 setColor(x, BLACK);
1893 }
1894
1895 private static final long serialVersionUID = 919286545866124006L;
1896
1897 /**
1898 * Save the state of the <tt>TreeMap</tt> instance to a stream (i.e.,
1899 * serialize it).
1900 *
1901 * @serialData The <i>size</i> of the TreeMap (the number of key-value
1902 * mappings) is emitted (int), followed by the key (Object)
1903 * and value (Object) for each key-value mapping represented
1904 * by the TreeMap. The key-value mappings are emitted in
1905 * key-order (as determined by the TreeMap's Comparator,
1906 * or by the keys' natural ordering if the TreeMap has no
1907 * Comparator).
1908 */
1909 private void writeObject(java.io.ObjectOutputStream s)
1910 throws java.io.IOException {
1911 // Write out the Comparator and any hidden stuff
1912 s.defaultWriteObject();
1913
1914 // Write out size (number of Mappings)
1915 s.writeInt(size);
1916
1917 // Write out keys and values (alternating)
1918 for (Iterator<Map.Entry<K,V>> i = entrySet().iterator(); i.hasNext(); ) {
1919 Map.Entry<K,V> e = i.next();
1920 s.writeObject(e.getKey());
1921 s.writeObject(e.getValue());
1922 }
1923 }
1924
1925
1926
1927 /**
1928 * Reconstitute the <tt>TreeMap</tt> instance from a stream (i.e.,
1929 * deserialize it).
1930 */
1931 private void readObject(final java.io.ObjectInputStream s)
1932 throws java.io.IOException, ClassNotFoundException {
1933 // Read in the Comparator and any hidden stuff
1934 s.defaultReadObject();
1935
1936 // Read in size
1937 int size = s.readInt();
1938
1939 buildFromSorted(size, null, s, null);
1940 }
1941
1942 /** Intended to be called only from TreeSet.readObject **/
1943 void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
1944 throws java.io.IOException, ClassNotFoundException {
1945 buildFromSorted(size, null, s, defaultVal);
1946 }
1947
1948 /** Intended to be called only from TreeSet.addAll **/
1949 void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
1950 try {
1951 buildFromSorted(set.size(), set.iterator(), null, defaultVal);
1952 } catch (java.io.IOException cannotHappen) {
1953 } catch (ClassNotFoundException cannotHappen) {
1954 }
1955 }
1956
1957
1958 /**
1959 * Linear time tree building algorithm from sorted data. Can accept keys
1960 * and/or values from iterator or stream. This leads to too many
1961 * parameters, but seems better than alternatives. The four formats
1962 * that this method accepts are:
1963 *
1964 * 1) An iterator of Map.Entries. (it != null, defaultVal == null).
1965 * 2) An iterator of keys. (it != null, defaultVal != null).
1966 * 3) A stream of alternating serialized keys and values.
1967 * (it == null, defaultVal == null).
1968 * 4) A stream of serialized keys. (it == null, defaultVal != null).
1969 *
1970 * It is assumed that the comparator of the TreeMap is already set prior
1971 * to calling this method.
1972 *
1973 * @param size the number of keys (or key-value pairs) to be read from
1974 * the iterator or stream
1975 * @param it If non-null, new entries are created from entries
1976 * or keys read from this iterator.
1977 * @param str If non-null, new entries are created from keys and
1978 * possibly values read from this stream in serialized form.
1979 * Exactly one of it and str should be non-null.
1980 * @param defaultVal if non-null, this default value is used for
1981 * each value in the map. If null, each value is read from
1982 * iterator or stream, as described above.
1983 * @throws IOException propagated from stream reads. This cannot
1984 * occur if str is null.
1985 * @throws ClassNotFoundException propagated from readObject.
1986 * This cannot occur if str is null.
1987 */
1988 private
1989 void buildFromSorted(int size, Iterator it,
1990 java.io.ObjectInputStream str,
1991 V defaultVal)
1992 throws java.io.IOException, ClassNotFoundException {
1993 this.size = size;
1994 root =
1995 buildFromSorted(0, 0, size-1, computeRedLevel(size),
1996 it, str, defaultVal);
1997 }
1998
1999 /**
2000 * Recursive "helper method" that does the real work of the
2001 * of the previous method. Identically named parameters have
2002 * identical definitions. Additional parameters are documented below.
2003 * It is assumed that the comparator and size fields of the TreeMap are
2004 * already set prior to calling this method. (It ignores both fields.)
2005 *
2006 * @param level the current level of tree. Initial call should be 0.
2007 * @param lo the first element index of this subtree. Initial should be 0.
2008 * @param hi the last element index of this subtree. Initial should be
2009 * size-1.
2010 * @param redLevel the level at which nodes should be red.
2011 * Must be equal to computeRedLevel for tree of this size.
2012 */
2013 private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
2014 int redLevel,
2015 Iterator it,
2016 java.io.ObjectInputStream str,
2017 V defaultVal)
2018 throws java.io.IOException, ClassNotFoundException {
2019 /*
2020 * Strategy: The root is the middlemost element. To get to it, we
2021 * have to first recursively construct the entire left subtree,
2022 * so as to grab all of its elements. We can then proceed with right
2023 * subtree.
2024 *
2025 * The lo and hi arguments are the minimum and maximum
2026 * indices to pull out of the iterator or stream for current subtree.
2027 * They are not actually indexed, we just proceed sequentially,
2028 * ensuring that items are extracted in corresponding order.
2029 */
2030
2031 if (hi < lo) return null;
2032
2033 int mid = (lo + hi) / 2;
2034
2035 Entry<K,V> left = null;
2036 if (lo < mid)
2037 left = buildFromSorted(level+1, lo, mid - 1, redLevel,
2038 it, str, defaultVal);
2039
2040 // extract key and/or value from iterator or stream
2041 K key;
2042 V value;
2043 if (it != null) {
2044 if (defaultVal==null) {
2045 Map.Entry<K,V> entry = (Map.Entry<K,V>)it.next();
2046 key = entry.getKey();
2047 value = entry.getValue();
2048 } else {
2049 key = (K)it.next();
2050 value = defaultVal;
2051 }
2052 } else { // use stream
2053 key = (K) str.readObject();
2054 value = (defaultVal != null ? defaultVal : (V) str.readObject());
2055 }
2056
2057 Entry<K,V> middle = new Entry<K,V>(key, value, null);
2058
2059 // color nodes in non-full bottommost level red
2060 if (level == redLevel)
2061 middle.color = RED;
2062
2063 if (left != null) {
2064 middle.left = left;
2065 left.parent = middle;
2066 }
2067
2068 if (mid < hi) {
2069 Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
2070 it, str, defaultVal);
2071 middle.right = right;
2072 right.parent = middle;
2073 }
2074
2075 return middle;
2076 }
2077
2078 /**
2079 * Find the level down to which to assign all nodes BLACK. This is the
2080 * last `full' level of the complete binary tree produced by
2081 * buildTree. The remaining nodes are colored RED. (This makes a `nice'
2082 * set of color assignments wrt future insertions.) This level number is
2083 * computed by finding the number of splits needed to reach the zeroeth
2084 * node. (The answer is ~lg(N), but in any case must be computed by same
2085 * quick O(lg(N)) loop.)
2086 */
2087 private static int computeRedLevel(int sz) {
2088 int level = 0;
2089 for (int m = sz - 1; m >= 0; m = m / 2 - 1)
2090 level++;
2091 return level;
2092 }
2093 }