1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.util;
28 
29 import java.io.Serializable;
30 import java.util.function.BiConsumer;
31 import java.util.function.BiFunction;
32 import java.util.function.Consumer;
33 import java.util.function.Function;
34 
35 /**
36  * A Red-Black tree based {@link NavigableMap} implementation.
37  * The map is sorted according to the {@linkplain Comparable natural
38  * ordering} of its keys, or by a {@link Comparator} provided at map
39  * creation time, depending on which constructor is used.
40  *
41  * <p>This implementation provides guaranteed log(n) time cost for the
42  * {@code containsKey}, {@code get}, {@code put} and {@code remove}
43  * operations.  Algorithms are adaptations of those in Cormen, Leiserson, and
44  * Rivest's <em>Introduction to Algorithms</em>.
45  *
46  * <p>Note that the ordering maintained by a tree map, like any sorted map, and
47  * whether or not an explicit comparator is provided, must be <em>consistent
48  * with {@code equals}</em> if this sorted map is to correctly implement the
49  * {@code Map} interface.  (See {@code Comparable} or {@code Comparator} for a
50  * precise definition of <em>consistent with equals</em>.)  This is so because
51  * the {@code Map} interface is defined in terms of the {@code equals}
52  * operation, but a sorted map performs all key comparisons using its {@code
53  * compareTo} (or {@code compare}) method, so two keys that are deemed equal by
54  * this method are, from the standpoint of the sorted map, equal.  The behavior
55  * of a sorted map <em>is</em> well-defined even if its ordering is
56  * inconsistent with {@code equals}; it just fails to obey the general contract
57  * of the {@code Map} interface.
58  *
59  * <p><strong>Note that this implementation is not synchronized.</strong>
60  * If multiple threads access a map concurrently, and at least one of the
61  * threads modifies the map structurally, it <em>must</em> be synchronized
62  * externally.  (A structural modification is any operation that adds or
63  * deletes one or more mappings; merely changing the value associated
64  * with an existing key is not a structural modification.)  This is
65  * typically accomplished by synchronizing on some object that naturally
66  * encapsulates the map.
67  * If no such object exists, the map should be "wrapped" using the
68  * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap}
69  * method.  This is best done at creation time, to prevent accidental
70  * unsynchronized access to the map: <pre>
71  *   SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre>
72  *
73  * <p>The iterators returned by the {@code iterator} method of the collections
74  * returned by all of this class's "collection view methods" are
75  * <em>fail-fast</em>: if the map is structurally modified at any time after
76  * the iterator is created, in any way except through the iterator's own
77  * {@code remove} method, the iterator will throw a {@link
78  * ConcurrentModificationException}.  Thus, in the face of concurrent
79  * modification, the iterator fails quickly and cleanly, rather than risking
80  * arbitrary, non-deterministic behavior at an undetermined time in the future.
81  *
82  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
83  * as it is, generally speaking, impossible to make any hard guarantees in the
84  * presence of unsynchronized concurrent modification.  Fail-fast iterators
85  * throw {@code ConcurrentModificationException} on a best-effort basis.
86  * Therefore, it would be wrong to write a program that depended on this
87  * exception for its correctness:   <em>the fail-fast behavior of iterators
88  * should be used only to detect bugs.</em>
89  *
90  * <p>The methods
91  * {@link #ceilingEntry},
92  * {@link #firstEntry},
93  * {@link #floorEntry},
94  * {@link #higherEntry},
95  * {@link #lastEntry},
96  * {@link #lowerEntry},
97  * {@link #pollFirstEntry}, and
98  * {@link #pollLastEntry}
99  * return {@link Map.Entry} instances that represent snapshots of mappings as
100  * of the time of the call. They do <em>not</em> support mutation of the
101  * underlying map via the optional {@link Map.Entry#setValue setValue} method.
102  *
103  * <p>The {@link #putFirst putFirst} and {@link #putLast putLast} methods of this class
104  * throw {@code UnsupportedOperationException}. The encounter order of mappings is determined
105  * by the comparison method; therefore, explicit positioning is not supported.
106  *
107  * <p>This class is a member of the
108  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
109  * Java Collections Framework</a>.
110  *
111  * @param <K> the type of keys maintained by this map
112  * @param <V> the type of mapped values
113  *
114  * @author  Josh Bloch and Doug Lea
115  * @see Map
116  * @see HashMap
117  * @see Hashtable
118  * @see Comparable
119  * @see Comparator
120  * @see Collection
121  * @since 1.2
122  */
123 
124 public class TreeMap<K,V>
125     extends AbstractMap<K,V>
126     implements NavigableMap<K,V>, Cloneable, java.io.Serializable
127 {
128     /**
129      * The comparator used to maintain order in this tree map, or
130      * null if it uses the natural ordering of its keys.
131      *
132      * @serial
133      */
134     @SuppressWarnings("serial") // Conditionally serializable
135     private final Comparator<? super K> comparator;
136 
137     private transient TreeMapEntry<K,V> root;
138 
139     /**
140      * The number of entries in the tree
141      */
142     private transient int size = 0;
143 
144     /**
145      * The number of structural modifications to the tree.
146      */
147     private transient int modCount = 0;
148 
149     /**
150      * Constructs a new, empty tree map, using the natural ordering of its
151      * keys.  All keys inserted into the map must implement the {@link
152      * Comparable} interface.  Furthermore, all such keys must be
153      * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
154      * a {@code ClassCastException} for any keys {@code k1} and
155      * {@code k2} in the map.  If the user attempts to put a key into the
156      * map that violates this constraint (for example, the user attempts to
157      * put a string key into a map whose keys are integers), the
158      * {@code put(Object key, Object value)} call will throw a
159      * {@code ClassCastException}.
160      */
TreeMap()161     public TreeMap() {
162         comparator = null;
163     }
164 
165     /**
166      * Constructs a new, empty tree map, ordered according to the given
167      * comparator.  All keys inserted into the map must be <em>mutually
168      * comparable</em> by the given comparator: {@code comparator.compare(k1,
169      * k2)} must not throw a {@code ClassCastException} for any keys
170      * {@code k1} and {@code k2} in the map.  If the user attempts to put
171      * a key into the map that violates this constraint, the {@code put(Object
172      * key, Object value)} call will throw a
173      * {@code ClassCastException}.
174      *
175      * @param comparator the comparator that will be used to order this map.
176      *        If {@code null}, the {@linkplain Comparable natural
177      *        ordering} of the keys will be used.
178      */
TreeMap(Comparator<? super K> comparator)179     public TreeMap(Comparator<? super K> comparator) {
180         this.comparator = comparator;
181     }
182 
183     /**
184      * Constructs a new tree map containing the same mappings as the given
185      * map, ordered according to the <em>natural ordering</em> of its keys.
186      * All keys inserted into the new map must implement the {@link
187      * Comparable} interface.  Furthermore, all such keys must be
188      * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
189      * a {@code ClassCastException} for any keys {@code k1} and
190      * {@code k2} in the map.  This method runs in n*log(n) time.
191      *
192      * @param  m the map whose mappings are to be placed in this map
193      * @throws ClassCastException if the keys in m are not {@link Comparable},
194      *         or are not mutually comparable
195      * @throws NullPointerException if the specified map is null
196      */
TreeMap(Map<? extends K, ? extends V> m)197     public TreeMap(Map<? extends K, ? extends V> m) {
198         comparator = null;
199         putAll(m);
200     }
201 
202     /**
203      * Constructs a new tree map containing the same mappings and
204      * using the same ordering as the specified sorted map.  This
205      * method runs in linear time.
206      *
207      * @param  m the sorted map whose mappings are to be placed in this map,
208      *         and whose comparator is to be used to sort this map
209      * @throws NullPointerException if the specified map is null
210      */
TreeMap(SortedMap<K, ? extends V> m)211     public TreeMap(SortedMap<K, ? extends V> m) {
212         comparator = m.comparator();
213         try {
214             buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
215         } catch (java.io.IOException | ClassNotFoundException cannotHappen) {
216         }
217     }
218 
219 
220     // Query Operations
221 
222     /**
223      * Returns the number of key-value mappings in this map.
224      *
225      * @return the number of key-value mappings in this map
226      */
size()227     public int size() {
228         return size;
229     }
230 
231     /**
232      * Returns {@code true} if this map contains a mapping for the specified
233      * key.
234      *
235      * @param key key whose presence in this map is to be tested
236      * @return {@code true} if this map contains a mapping for the
237      *         specified key
238      * @throws ClassCastException if the specified key cannot be compared
239      *         with the keys currently in the map
240      * @throws NullPointerException if the specified key is null
241      *         and this map uses natural ordering, or its comparator
242      *         does not permit null keys
243      */
containsKey(Object key)244     public boolean containsKey(Object key) {
245         return getEntry(key) != null;
246     }
247 
248     /**
249      * Returns {@code true} if this map maps one or more keys to the
250      * specified value.  More formally, returns {@code true} if and only if
251      * this map contains at least one mapping to a value {@code v} such
252      * that {@code (value==null ? v==null : value.equals(v))}.  This
253      * operation will probably require time linear in the map size for
254      * most implementations.
255      *
256      * @param value value whose presence in this map is to be tested
257      * @return {@code true} if a mapping to {@code value} exists;
258      *         {@code false} otherwise
259      * @since 1.2
260      */
containsValue(Object value)261     public boolean containsValue(Object value) {
262         for (TreeMapEntry<K,V> e = getFirstEntry(); e != null; e = successor(e))
263             if (valEquals(value, e.value))
264                 return true;
265         return false;
266     }
267 
268     /**
269      * Returns the value to which the specified key is mapped,
270      * or {@code null} if this map contains no mapping for the key.
271      *
272      * <p>More formally, if this map contains a mapping from a key
273      * {@code k} to a value {@code v} such that {@code key} compares
274      * equal to {@code k} according to the map's ordering, then this
275      * method returns {@code v}; otherwise it returns {@code null}.
276      * (There can be at most one such mapping.)
277      *
278      * <p>A return value of {@code null} does not <em>necessarily</em>
279      * indicate that the map contains no mapping for the key; it's also
280      * possible that the map explicitly maps the key to {@code null}.
281      * The {@link #containsKey containsKey} operation may be used to
282      * distinguish these two cases.
283      *
284      * @throws ClassCastException if the specified key cannot be compared
285      *         with the keys currently in the map
286      * @throws NullPointerException if the specified key is null
287      *         and this map uses natural ordering, or its comparator
288      *         does not permit null keys
289      */
get(Object key)290     public V get(Object key) {
291         TreeMapEntry<K,V> p = getEntry(key);
292         return (p==null ? null : p.value);
293     }
294 
comparator()295     public Comparator<? super K> comparator() {
296         return comparator;
297     }
298 
299     /**
300      * @throws NoSuchElementException {@inheritDoc}
301      */
firstKey()302     public K firstKey() {
303         return key(getFirstEntry());
304     }
305 
306     /**
307      * @throws NoSuchElementException {@inheritDoc}
308      */
lastKey()309     public K lastKey() {
310         return key(getLastEntry());
311     }
312 
313     /**
314      * Throws {@code UnsupportedOperationException}. The encounter order induced by this
315      * map's comparison method determines the position of mappings, so explicit positioning
316      * is not supported.
317      *
318      * @throws UnsupportedOperationException always
319      * @since 21
320      */
putFirst(K k, V v)321      public V putFirst(K k, V v) {
322         throw new UnsupportedOperationException();
323     }
324 
325     /**
326      * Throws {@code UnsupportedOperationException}. The encounter order induced by this
327      * map's comparison method determines the position of mappings, so explicit positioning
328      * is not supported.
329      *
330      * @throws UnsupportedOperationException always
331      * @since 21
332      */
putLast(K k, V v)333     public V putLast(K k, V v) {
334         throw new UnsupportedOperationException();
335     }
336 
337     /**
338      * Copies all of the mappings from the specified map to this map.
339      * These mappings replace any mappings that this map had for any
340      * of the keys currently in the specified map.
341      *
342      * @param  map mappings to be stored in this map
343      * @throws ClassCastException if the class of a key or value in
344      *         the specified map prevents it from being stored in this map
345      * @throws NullPointerException if the specified map is null or
346      *         the specified map contains a null key and this map does not
347      *         permit null keys
348      */
putAll(Map<? extends K, ? extends V> map)349     public void putAll(Map<? extends K, ? extends V> map) {
350         int mapSize = map.size();
351         if (size==0 && mapSize!=0 && map instanceof SortedMap) {
352             if (Objects.equals(comparator, ((SortedMap<?,?>)map).comparator())) {
353                 ++modCount;
354                 try {
355                     buildFromSorted(mapSize, map.entrySet().iterator(),
356                                     null, null);
357                 } catch (java.io.IOException | ClassNotFoundException cannotHappen) {
358                 }
359                 return;
360             }
361         }
362         super.putAll(map);
363     }
364 
365     /**
366      * Returns this map's entry for the given key, or {@code null} if the map
367      * does not contain an entry for the key.
368      *
369      * @return this map's entry for the given key, or {@code null} if the map
370      *         does not contain an entry for the key
371      * @throws ClassCastException if the specified key cannot be compared
372      *         with the keys currently in the map
373      * @throws NullPointerException if the specified key is null
374      *         and this map uses natural ordering, or its comparator
375      *         does not permit null keys
376      */
getEntry(Object key)377     final TreeMapEntry<K,V> getEntry(Object key) {
378         // Offload comparator-based version for sake of performance
379         if (comparator != null)
380             return getEntryUsingComparator(key);
381         Objects.requireNonNull(key);
382         @SuppressWarnings("unchecked")
383             Comparable<? super K> k = (Comparable<? super K>) key;
384         TreeMapEntry<K,V> p = root;
385         while (p != null) {
386             int cmp = k.compareTo(p.key);
387             if (cmp < 0)
388                 p = p.left;
389             else if (cmp > 0)
390                 p = p.right;
391             else
392                 return p;
393         }
394         return null;
395     }
396 
397     /**
398      * Version of getEntry using comparator. Split off from getEntry
399      * for performance. (This is not worth doing for most methods,
400      * that are less dependent on comparator performance, but is
401      * worthwhile here.)
402      */
getEntryUsingComparator(Object key)403     final TreeMapEntry<K,V> getEntryUsingComparator(Object key) {
404         @SuppressWarnings("unchecked")
405             K k = (K) key;
406         Comparator<? super K> cpr = comparator;
407         if (cpr != null) {
408             TreeMapEntry<K,V> p = root;
409             while (p != null) {
410                 int cmp = cpr.compare(k, p.key);
411                 if (cmp < 0)
412                     p = p.left;
413                 else if (cmp > 0)
414                     p = p.right;
415                 else
416                     return p;
417             }
418         }
419         return null;
420     }
421 
422     /**
423      * Gets the entry corresponding to the specified key; if no such entry
424      * exists, returns the entry for the least key greater than the specified
425      * key; if no such entry exists (i.e., the greatest key in the Tree is less
426      * than the specified key), returns {@code null}.
427      */
getCeilingEntry(K key)428     final TreeMapEntry<K,V> getCeilingEntry(K key) {
429         TreeMapEntry<K,V> p = root;
430         while (p != null) {
431             int cmp = compare(key, p.key);
432             if (cmp < 0) {
433                 if (p.left != null)
434                     p = p.left;
435                 else
436                     return p;
437             } else if (cmp > 0) {
438                 if (p.right != null) {
439                     p = p.right;
440                 } else {
441                     TreeMapEntry<K,V> parent = p.parent;
442                     TreeMapEntry<K,V> ch = p;
443                     while (parent != null && ch == parent.right) {
444                         ch = parent;
445                         parent = parent.parent;
446                     }
447                     return parent;
448                 }
449             } else
450                 return p;
451         }
452         return null;
453     }
454 
455     /**
456      * Gets the entry corresponding to the specified key; if no such entry
457      * exists, returns the entry for the greatest key less than the specified
458      * key; if no such entry exists (i.e., the least key in the Tree is greater
459      * than the specified key), returns {@code null}.
460      */
getFloorEntry(K key)461     final TreeMapEntry<K,V> getFloorEntry(K key) {
462         TreeMapEntry<K,V> p = root;
463         while (p != null) {
464             int cmp = compare(key, p.key);
465             if (cmp > 0) {
466                 if (p.right != null)
467                     p = p.right;
468                 else
469                     return p;
470             } else if (cmp < 0) {
471                 if (p.left != null) {
472                     p = p.left;
473                 } else {
474                     TreeMapEntry<K,V> parent = p.parent;
475                     TreeMapEntry<K,V> ch = p;
476                     while (parent != null && ch == parent.left) {
477                         ch = parent;
478                         parent = parent.parent;
479                     }
480                     return parent;
481                 }
482             } else
483                 return p;
484 
485         }
486         return null;
487     }
488 
489     /**
490      * Returns the entry for the least key greater than the specified key; if
491      * no such entry exists (i.e., the greatest key in the Tree is less than
492      * or equal to the specified key), returns {@code null}.
493      */
getHigherEntry(K key)494     final TreeMapEntry<K,V> getHigherEntry(K key) {
495         TreeMapEntry<K,V> p = root;
496         while (p != null) {
497             int cmp = compare(key, p.key);
498             if (cmp < 0) {
499                 if (p.left != null)
500                     p = p.left;
501                 else
502                     return p;
503             } else {
504                 if (p.right != null) {
505                     p = p.right;
506                 } else {
507                     TreeMapEntry<K,V> parent = p.parent;
508                     TreeMapEntry<K,V> ch = p;
509                     while (parent != null && ch == parent.right) {
510                         ch = parent;
511                         parent = parent.parent;
512                     }
513                     return parent;
514                 }
515             }
516         }
517         return null;
518     }
519 
520     /**
521      * Returns the entry for the greatest key less than the specified key; if
522      * no such entry exists (i.e., the least key in the Tree is greater than
523      * or equal to the specified key), returns {@code null}.
524      */
getLowerEntry(K key)525     final TreeMapEntry<K,V> getLowerEntry(K key) {
526         TreeMapEntry<K,V> p = root;
527         while (p != null) {
528             int cmp = compare(key, p.key);
529             if (cmp > 0) {
530                 if (p.right != null)
531                     p = p.right;
532                 else
533                     return p;
534             } else {
535                 if (p.left != null) {
536                     p = p.left;
537                 } else {
538                     TreeMapEntry<K,V> parent = p.parent;
539                     TreeMapEntry<K,V> ch = p;
540                     while (parent != null && ch == parent.left) {
541                         ch = parent;
542                         parent = parent.parent;
543                     }
544                     return parent;
545                 }
546             }
547         }
548         return null;
549     }
550 
551     /**
552      * Associates the specified value with the specified key in this map.
553      * If the map previously contained a mapping for the key, the old
554      * value is replaced.
555      *
556      * @param key key with which the specified value is to be associated
557      * @param value value to be associated with the specified key
558      *
559      * @return the previous value associated with {@code key}, or
560      *         {@code null} if there was no mapping for {@code key}.
561      *         (A {@code null} return can also indicate that the map
562      *         previously associated {@code null} with {@code key}.)
563      * @throws ClassCastException if the specified key cannot be compared
564      *         with the keys currently in the map
565      * @throws NullPointerException if the specified key is null
566      *         and this map uses natural ordering, or its comparator
567      *         does not permit null keys
568      */
put(K key, V value)569     public V put(K key, V value) {
570         return put(key, value, true);
571     }
572 
573     @Override
putIfAbsent(K key, V value)574     public V putIfAbsent(K key, V value) {
575         return put(key, value, false);
576     }
577 
578     /**
579      * {@inheritDoc}
580      *
581      * <p>This method will, on a best-effort basis, throw a
582      * {@link ConcurrentModificationException} if it is detected that the
583      * mapping function modifies this map during computation.
584      *
585      * @throws ConcurrentModificationException if it is detected that the
586      * mapping function modified this map
587      */
588     @Override
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)589     public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
590         Objects.requireNonNull(mappingFunction);
591         V newValue;
592         TreeMapEntry<K,V> t = root;
593         if (t == null) {
594             newValue = callMappingFunctionWithCheck(key, mappingFunction);
595             if (newValue != null) {
596                 addEntryToEmptyMap(key, newValue);
597                 return newValue;
598             } else {
599                 return null;
600             }
601         }
602         int cmp;
603         TreeMapEntry<K,V> parent;
604         // split comparator and comparable paths
605         Comparator<? super K> cpr = comparator;
606         if (cpr != null) {
607             do {
608                 parent = t;
609                 cmp = cpr.compare(key, t.key);
610                 if (cmp < 0)
611                     t = t.left;
612                 else if (cmp > 0)
613                     t = t.right;
614                 else {
615                     if (t.value == null) {
616                         t.value = callMappingFunctionWithCheck(key, mappingFunction);
617                     }
618                     return t.value;
619                 }
620             } while (t != null);
621         } else {
622             Objects.requireNonNull(key);
623             @SuppressWarnings("unchecked")
624             Comparable<? super K> k = (Comparable<? super K>) key;
625             do {
626                 parent = t;
627                 cmp = k.compareTo(t.key);
628                 if (cmp < 0)
629                     t = t.left;
630                 else if (cmp > 0)
631                     t = t.right;
632                 else {
633                     if (t.value == null) {
634                         t.value = callMappingFunctionWithCheck(key, mappingFunction);
635                     }
636                     return t.value;
637                 }
638             } while (t != null);
639         }
640         newValue = callMappingFunctionWithCheck(key, mappingFunction);
641         if (newValue != null) {
642             addEntry(key, newValue, parent, cmp < 0);
643             return newValue;
644         }
645         return null;
646     }
647 
648     /**
649      * {@inheritDoc}
650      *
651      * <p>This method will, on a best-effort basis, throw a
652      * {@link ConcurrentModificationException} if it is detected that the
653      * remapping function modifies this map during computation.
654      *
655      * @throws ConcurrentModificationException if it is detected that the
656      * remapping function modified this map
657      */
658     @Override
computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)659     public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
660         Objects.requireNonNull(remappingFunction);
661         TreeMapEntry<K,V> oldEntry = getEntry(key);
662         if (oldEntry != null && oldEntry.value != null) {
663             return remapValue(oldEntry, key, remappingFunction);
664         } else {
665             return null;
666         }
667     }
668 
669     /**
670      * {@inheritDoc}
671      *
672      * <p>This method will, on a best-effort basis, throw a
673      * {@link ConcurrentModificationException} if it is detected that the
674      * remapping function modifies this map during computation.
675      *
676      * @throws ConcurrentModificationException if it is detected that the
677      * remapping function modified this map
678      */
679     @Override
compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)680     public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
681         Objects.requireNonNull(remappingFunction);
682         V newValue;
683         TreeMapEntry<K,V> t = root;
684         if (t == null) {
685             newValue = callRemappingFunctionWithCheck(key, null, remappingFunction);
686             if (newValue != null) {
687                 addEntryToEmptyMap(key, newValue);
688                 return newValue;
689             } else {
690                 return null;
691             }
692         }
693         int cmp;
694         TreeMapEntry<K,V> parent;
695         // split comparator and comparable paths
696         Comparator<? super K> cpr = comparator;
697         if (cpr != null) {
698             do {
699                 parent = t;
700                 cmp = cpr.compare(key, t.key);
701                 if (cmp < 0)
702                     t = t.left;
703                 else if (cmp > 0)
704                     t = t.right;
705                 else
706                     return remapValue(t, key, remappingFunction);
707             } while (t != null);
708         } else {
709             Objects.requireNonNull(key);
710             @SuppressWarnings("unchecked")
711             Comparable<? super K> k = (Comparable<? super K>) key;
712             do {
713                 parent = t;
714                 cmp = k.compareTo(t.key);
715                 if (cmp < 0)
716                     t = t.left;
717                 else if (cmp > 0)
718                     t = t.right;
719                 else
720                     return remapValue(t, key, remappingFunction);
721             } while (t != null);
722         }
723         newValue = callRemappingFunctionWithCheck(key, null, remappingFunction);
724         if (newValue != null) {
725             addEntry(key, newValue, parent, cmp < 0);
726             return newValue;
727         }
728         return null;
729     }
730 
731     /**
732      * {@inheritDoc}
733      *
734      * <p>This method will, on a best-effort basis, throw a
735      * {@link ConcurrentModificationException} if it is detected that the
736      * remapping function modifies this map during computation.
737      *
738      * @throws ConcurrentModificationException if it is detected that the
739      * remapping function modified this map
740      */
741     @Override
merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)742     public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
743         Objects.requireNonNull(remappingFunction);
744         Objects.requireNonNull(value);
745         TreeMapEntry<K,V> t = root;
746         if (t == null) {
747             addEntryToEmptyMap(key, value);
748             return value;
749         }
750         int cmp;
751         TreeMapEntry<K,V> parent;
752         // split comparator and comparable paths
753         Comparator<? super K> cpr = comparator;
754         if (cpr != null) {
755             do {
756                 parent = t;
757                 cmp = cpr.compare(key, t.key);
758                 if (cmp < 0)
759                     t = t.left;
760                 else if (cmp > 0)
761                     t = t.right;
762                 else return mergeValue(t, value, remappingFunction);
763             } while (t != null);
764         } else {
765             Objects.requireNonNull(key);
766             @SuppressWarnings("unchecked")
767             Comparable<? super K> k = (Comparable<? super K>) key;
768             do {
769                 parent = t;
770                 cmp = k.compareTo(t.key);
771                 if (cmp < 0)
772                     t = t.left;
773                 else if (cmp > 0)
774                     t = t.right;
775                 else return mergeValue(t, value, remappingFunction);
776             } while (t != null);
777         }
778         addEntry(key, value, parent, cmp < 0);
779         return value;
780     }
781 
callMappingFunctionWithCheck(K key, Function<? super K, ? extends V> mappingFunction)782     private V callMappingFunctionWithCheck(K key, Function<? super K, ? extends V> mappingFunction) {
783         int mc = modCount;
784         V newValue = mappingFunction.apply(key);
785         if (mc != modCount) {
786             throw new ConcurrentModificationException();
787         }
788         return newValue;
789     }
790 
callRemappingFunctionWithCheck(K key, V oldValue, BiFunction<? super K, ? super V, ? extends V> remappingFunction)791     private V callRemappingFunctionWithCheck(K key, V oldValue, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
792         int mc = modCount;
793         V newValue = remappingFunction.apply(key, oldValue);
794         if (mc != modCount) {
795             throw new ConcurrentModificationException();
796         }
797         return newValue;
798     }
799 
addEntry(K key, V value, TreeMapEntry<K, V> parent, boolean addToLeft)800     private void addEntry(K key, V value, TreeMapEntry<K, V> parent, boolean addToLeft) {
801         TreeMapEntry<K,V> e = new TreeMapEntry<>(key, value, parent);
802         if (addToLeft)
803             parent.left = e;
804         else
805             parent.right = e;
806         fixAfterInsertion(e);
807         size++;
808         modCount++;
809     }
810 
addEntryToEmptyMap(K key, V value)811     private void addEntryToEmptyMap(K key, V value) {
812         compare(key, key); // type (and possibly null) check
813         root = new TreeMapEntry<>(key, value, null);
814         size = 1;
815         modCount++;
816     }
817 
put(K key, V value, boolean replaceOld)818     private V put(K key, V value, boolean replaceOld) {
819         TreeMapEntry<K,V> t = root;
820         if (t == null) {
821             addEntryToEmptyMap(key, value);
822             return null;
823         }
824         int cmp;
825         TreeMapEntry<K,V> parent;
826         // split comparator and comparable paths
827         Comparator<? super K> cpr = comparator;
828         if (cpr != null) {
829             do {
830                 parent = t;
831                 cmp = cpr.compare(key, t.key);
832                 if (cmp < 0)
833                     t = t.left;
834                 else if (cmp > 0)
835                     t = t.right;
836                 else {
837                     V oldValue = t.value;
838                     if (replaceOld || oldValue == null) {
839                         t.value = value;
840                     }
841                     return oldValue;
842                 }
843             } while (t != null);
844         } else {
845             Objects.requireNonNull(key);
846             @SuppressWarnings("unchecked")
847             Comparable<? super K> k = (Comparable<? super K>) key;
848             do {
849                 parent = t;
850                 cmp = k.compareTo(t.key);
851                 if (cmp < 0)
852                     t = t.left;
853                 else if (cmp > 0)
854                     t = t.right;
855                 else {
856                     V oldValue = t.value;
857                     if (replaceOld || oldValue == null) {
858                         t.value = value;
859                     }
860                     return oldValue;
861                 }
862             } while (t != null);
863         }
864         addEntry(key, value, parent, cmp < 0);
865         return null;
866     }
867 
remapValue(TreeMapEntry<K,V> t, K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)868     private V remapValue(TreeMapEntry<K,V> t, K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
869         V newValue = callRemappingFunctionWithCheck(key, t.value, remappingFunction);
870         if (newValue == null) {
871             deleteEntry(t);
872             return null;
873         } else {
874             // replace old mapping
875             t.value = newValue;
876             return newValue;
877         }
878     }
879 
mergeValue(TreeMapEntry<K,V> t, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)880     private V mergeValue(TreeMapEntry<K,V> t, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
881         V oldValue = t.value;
882         V newValue;
883         if (t.value == null) {
884             newValue = value;
885         } else {
886             int mc = modCount;
887             newValue = remappingFunction.apply(oldValue, value);
888             if (mc != modCount) {
889                 throw new ConcurrentModificationException();
890             }
891         }
892         if (newValue == null) {
893             deleteEntry(t);
894             return null;
895         } else {
896             // replace old mapping
897             t.value = newValue;
898             return newValue;
899         }
900     }
901 
902     /**
903      * Removes the mapping for this key from this TreeMap if present.
904      *
905      * @param  key key for which mapping should be removed
906      * @return the previous value associated with {@code key}, or
907      *         {@code null} if there was no mapping for {@code key}.
908      *         (A {@code null} return can also indicate that the map
909      *         previously associated {@code null} with {@code key}.)
910      * @throws ClassCastException if the specified key cannot be compared
911      *         with the keys currently in the map
912      * @throws NullPointerException if the specified key is null
913      *         and this map uses natural ordering, or its comparator
914      *         does not permit null keys
915      */
remove(Object key)916     public V remove(Object key) {
917         TreeMapEntry<K,V> p = getEntry(key);
918         if (p == null)
919             return null;
920 
921         V oldValue = p.value;
922         deleteEntry(p);
923         return oldValue;
924     }
925 
926     /**
927      * Removes all of the mappings from this map.
928      * The map will be empty after this call returns.
929      */
clear()930     public void clear() {
931         modCount++;
932         size = 0;
933         root = null;
934     }
935 
936     /**
937      * Returns a shallow copy of this {@code TreeMap} instance. (The keys and
938      * values themselves are not cloned.)
939      *
940      * @return a shallow copy of this map
941      */
clone()942     public Object clone() {
943         TreeMap<?,?> clone;
944         try {
945             clone = (TreeMap<?,?>) super.clone();
946         } catch (CloneNotSupportedException e) {
947             throw new InternalError(e);
948         }
949 
950         // Put clone into "virgin" state (except for comparator)
951         clone.root = null;
952         clone.size = 0;
953         clone.modCount = 0;
954         clone.entrySet = null;
955         clone.navigableKeySet = null;
956         clone.descendingMap = null;
957 
958         // Initialize clone with our mappings
959         try {
960             clone.buildFromSorted(size, entrySet().iterator(), null, null);
961         } catch (java.io.IOException | ClassNotFoundException cannotHappen) {
962         }
963 
964         return clone;
965     }
966 
967     // NavigableMap API methods
968 
969     /**
970      * @since 1.6
971      */
firstEntry()972     public Map.Entry<K,V> firstEntry() {
973         return exportEntry(getFirstEntry());
974     }
975 
976     /**
977      * @since 1.6
978      */
lastEntry()979     public Map.Entry<K,V> lastEntry() {
980         return exportEntry(getLastEntry());
981     }
982 
983     /**
984      * @since 1.6
985      */
pollFirstEntry()986     public Map.Entry<K,V> pollFirstEntry() {
987         TreeMapEntry<K,V> p = getFirstEntry();
988         Map.Entry<K,V> result = exportEntry(p);
989         if (p != null)
990             deleteEntry(p);
991         return result;
992     }
993 
994     /**
995      * @since 1.6
996      */
pollLastEntry()997     public Map.Entry<K,V> pollLastEntry() {
998         TreeMapEntry<K,V> p = getLastEntry();
999         Map.Entry<K,V> result = exportEntry(p);
1000         if (p != null)
1001             deleteEntry(p);
1002         return result;
1003     }
1004 
1005     /**
1006      * @throws ClassCastException {@inheritDoc}
1007      * @throws NullPointerException if the specified key is null
1008      *         and this map uses natural ordering, or its comparator
1009      *         does not permit null keys
1010      * @since 1.6
1011      */
lowerEntry(K key)1012     public Map.Entry<K,V> lowerEntry(K key) {
1013         return exportEntry(getLowerEntry(key));
1014     }
1015 
1016     /**
1017      * @throws ClassCastException {@inheritDoc}
1018      * @throws NullPointerException if the specified key is null
1019      *         and this map uses natural ordering, or its comparator
1020      *         does not permit null keys
1021      * @since 1.6
1022      */
lowerKey(K key)1023     public K lowerKey(K key) {
1024         return keyOrNull(getLowerEntry(key));
1025     }
1026 
1027     /**
1028      * @throws ClassCastException {@inheritDoc}
1029      * @throws NullPointerException if the specified key is null
1030      *         and this map uses natural ordering, or its comparator
1031      *         does not permit null keys
1032      * @since 1.6
1033      */
floorEntry(K key)1034     public Map.Entry<K,V> floorEntry(K key) {
1035         return exportEntry(getFloorEntry(key));
1036     }
1037 
1038     /**
1039      * @throws ClassCastException {@inheritDoc}
1040      * @throws NullPointerException if the specified key is null
1041      *         and this map uses natural ordering, or its comparator
1042      *         does not permit null keys
1043      * @since 1.6
1044      */
floorKey(K key)1045     public K floorKey(K key) {
1046         return keyOrNull(getFloorEntry(key));
1047     }
1048 
1049     /**
1050      * @throws ClassCastException {@inheritDoc}
1051      * @throws NullPointerException if the specified key is null
1052      *         and this map uses natural ordering, or its comparator
1053      *         does not permit null keys
1054      * @since 1.6
1055      */
ceilingEntry(K key)1056     public Map.Entry<K,V> ceilingEntry(K key) {
1057         return exportEntry(getCeilingEntry(key));
1058     }
1059 
1060     /**
1061      * @throws ClassCastException {@inheritDoc}
1062      * @throws NullPointerException if the specified key is null
1063      *         and this map uses natural ordering, or its comparator
1064      *         does not permit null keys
1065      * @since 1.6
1066      */
ceilingKey(K key)1067     public K ceilingKey(K key) {
1068         return keyOrNull(getCeilingEntry(key));
1069     }
1070 
1071     /**
1072      * @throws ClassCastException {@inheritDoc}
1073      * @throws NullPointerException if the specified key is null
1074      *         and this map uses natural ordering, or its comparator
1075      *         does not permit null keys
1076      * @since 1.6
1077      */
higherEntry(K key)1078     public Map.Entry<K,V> higherEntry(K key) {
1079         return exportEntry(getHigherEntry(key));
1080     }
1081 
1082     /**
1083      * @throws ClassCastException {@inheritDoc}
1084      * @throws NullPointerException if the specified key is null
1085      *         and this map uses natural ordering, or its comparator
1086      *         does not permit null keys
1087      * @since 1.6
1088      */
higherKey(K key)1089     public K higherKey(K key) {
1090         return keyOrNull(getHigherEntry(key));
1091     }
1092 
1093     // Views
1094 
1095     /**
1096      * Fields initialized to contain an instance of the entry set view
1097      * the first time this view is requested.  Views are stateless, so
1098      * there's no reason to create more than one.
1099      */
1100     private transient EntrySet entrySet;
1101     private transient KeySet<K> navigableKeySet;
1102     private transient NavigableMap<K,V> descendingMap;
1103 
1104     /**
1105      * Returns a {@link Set} view of the keys contained in this map.
1106      *
1107      * <p>The set's iterator returns the keys in ascending order.
1108      * The set's spliterator is
1109      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
1110      * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED}
1111      * and {@link Spliterator#ORDERED} with an encounter order that is ascending
1112      * key order.  The spliterator's comparator (see
1113      * {@link java.util.Spliterator#getComparator()}) is {@code null} if
1114      * the tree map's comparator (see {@link #comparator()}) is {@code null}.
1115      * Otherwise, the spliterator's comparator is the same as or imposes the
1116      * same total ordering as the tree map's comparator.
1117      *
1118      * <p>The set is backed by the map, so changes to the map are
1119      * reflected in the set, and vice-versa.  If the map is modified
1120      * while an iteration over the set is in progress (except through
1121      * the iterator's own {@code remove} operation), the results of
1122      * the iteration are undefined.  The set supports element removal,
1123      * which removes the corresponding mapping from the map, via the
1124      * {@code Iterator.remove}, {@code Set.remove},
1125      * {@code removeAll}, {@code retainAll}, and {@code clear}
1126      * operations.  It does not support the {@code add} or {@code addAll}
1127      * operations.
1128      */
keySet()1129     public Set<K> keySet() {
1130         return navigableKeySet();
1131     }
1132 
1133     /**
1134      * @since 1.6
1135      */
navigableKeySet()1136     public NavigableSet<K> navigableKeySet() {
1137         KeySet<K> nks = navigableKeySet;
1138         return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));
1139     }
1140 
1141     /**
1142      * @since 1.6
1143      */
descendingKeySet()1144     public NavigableSet<K> descendingKeySet() {
1145         return descendingMap().navigableKeySet();
1146     }
1147 
1148     /**
1149      * Returns a {@link Collection} view of the values contained in this map.
1150      *
1151      * <p>The collection's iterator returns the values in ascending order
1152      * of the corresponding keys. The collection's spliterator is
1153      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
1154      * <em>fail-fast</em>, and additionally reports {@link Spliterator#ORDERED}
1155      * with an encounter order that is ascending order of the corresponding
1156      * keys.
1157      *
1158      * <p>The collection is backed by the map, so changes to the map are
1159      * reflected in the collection, and vice-versa.  If the map is
1160      * modified while an iteration over the collection is in progress
1161      * (except through the iterator's own {@code remove} operation),
1162      * the results of the iteration are undefined.  The collection
1163      * supports element removal, which removes the corresponding
1164      * mapping from the map, via the {@code Iterator.remove},
1165      * {@code Collection.remove}, {@code removeAll},
1166      * {@code retainAll} and {@code clear} operations.  It does not
1167      * support the {@code add} or {@code addAll} operations.
1168      */
values()1169     public Collection<V> values() {
1170         Collection<V> vs = values;
1171         if (vs == null) {
1172             vs = new Values();
1173             values = vs;
1174         }
1175         return vs;
1176     }
1177 
1178     /**
1179      * Returns a {@link Set} view of the mappings contained in this map.
1180      *
1181      * <p>The set's iterator returns the entries in ascending key order. The
1182      * set's spliterator is
1183      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
1184      * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and
1185      * {@link Spliterator#ORDERED} with an encounter order that is ascending key
1186      * order.
1187      *
1188      * <p>The set is backed by the map, so changes to the map are
1189      * reflected in the set, and vice-versa.  If the map is modified
1190      * while an iteration over the set is in progress (except through
1191      * the iterator's own {@code remove} operation, or through the
1192      * {@code setValue} operation on a map entry returned by the
1193      * iterator) the results of the iteration are undefined.  The set
1194      * supports element removal, which removes the corresponding
1195      * mapping from the map, via the {@code Iterator.remove},
1196      * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
1197      * {@code clear} operations.  It does not support the
1198      * {@code add} or {@code addAll} operations.
1199      */
entrySet()1200     public Set<Map.Entry<K,V>> entrySet() {
1201         EntrySet es = entrySet;
1202         return (es != null) ? es : (entrySet = new EntrySet());
1203     }
1204 
1205     /**
1206      * @since 1.6
1207      */
descendingMap()1208     public NavigableMap<K, V> descendingMap() {
1209         NavigableMap<K, V> km = descendingMap;
1210         return (km != null) ? km :
1211             (descendingMap = new DescendingSubMap<>(this,
1212                                                     true, null, true,
1213                                                     true, null, true));
1214     }
1215 
1216     /**
1217      * @throws ClassCastException       {@inheritDoc}
1218      * @throws NullPointerException if {@code fromKey} or {@code toKey} is
1219      *         null and this map uses natural ordering, or its comparator
1220      *         does not permit null keys
1221      * @throws IllegalArgumentException {@inheritDoc}
1222      * @since 1.6
1223      */
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)1224     public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
1225                                     K toKey,   boolean toInclusive) {
1226         return new AscendingSubMap<>(this,
1227                                      false, fromKey, fromInclusive,
1228                                      false, toKey,   toInclusive);
1229     }
1230 
1231     /**
1232      * @throws ClassCastException       {@inheritDoc}
1233      * @throws NullPointerException if {@code toKey} is null
1234      *         and this map uses natural ordering, or its comparator
1235      *         does not permit null keys
1236      * @throws IllegalArgumentException {@inheritDoc}
1237      * @since 1.6
1238      */
headMap(K toKey, boolean inclusive)1239     public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
1240         return new AscendingSubMap<>(this,
1241                                      true,  null,  true,
1242                                      false, toKey, inclusive);
1243     }
1244 
1245     /**
1246      * @throws ClassCastException       {@inheritDoc}
1247      * @throws NullPointerException if {@code fromKey} is null
1248      *         and this map uses natural ordering, or its comparator
1249      *         does not permit null keys
1250      * @throws IllegalArgumentException {@inheritDoc}
1251      * @since 1.6
1252      */
tailMap(K fromKey, boolean inclusive)1253     public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
1254         return new AscendingSubMap<>(this,
1255                                      false, fromKey, inclusive,
1256                                      true,  null,    true);
1257     }
1258 
1259     /**
1260      * @throws ClassCastException       {@inheritDoc}
1261      * @throws NullPointerException if {@code fromKey} or {@code toKey} is
1262      *         null and this map uses natural ordering, or its comparator
1263      *         does not permit null keys
1264      * @throws IllegalArgumentException {@inheritDoc}
1265      */
subMap(K fromKey, K toKey)1266     public SortedMap<K,V> subMap(K fromKey, K toKey) {
1267         return subMap(fromKey, true, toKey, false);
1268     }
1269 
1270     /**
1271      * @throws ClassCastException       {@inheritDoc}
1272      * @throws NullPointerException if {@code toKey} is null
1273      *         and this map uses natural ordering, or its comparator
1274      *         does not permit null keys
1275      * @throws IllegalArgumentException {@inheritDoc}
1276      */
headMap(K toKey)1277     public SortedMap<K,V> headMap(K toKey) {
1278         return headMap(toKey, false);
1279     }
1280 
1281     /**
1282      * @throws ClassCastException       {@inheritDoc}
1283      * @throws NullPointerException if {@code fromKey} is null
1284      *         and this map uses natural ordering, or its comparator
1285      *         does not permit null keys
1286      * @throws IllegalArgumentException {@inheritDoc}
1287      */
tailMap(K fromKey)1288     public SortedMap<K,V> tailMap(K fromKey) {
1289         return tailMap(fromKey, true);
1290     }
1291 
1292     @Override
replace(K key, V oldValue, V newValue)1293     public boolean replace(K key, V oldValue, V newValue) {
1294         TreeMapEntry<K,V> p = getEntry(key);
1295         if (p!=null && Objects.equals(oldValue, p.value)) {
1296             p.value = newValue;
1297             return true;
1298         }
1299         return false;
1300     }
1301 
1302     @Override
replace(K key, V value)1303     public V replace(K key, V value) {
1304         TreeMapEntry<K,V> p = getEntry(key);
1305         if (p!=null) {
1306             V oldValue = p.value;
1307             p.value = value;
1308             return oldValue;
1309         }
1310         return null;
1311     }
1312 
1313     @Override
forEach(BiConsumer<? super K, ? super V> action)1314     public void forEach(BiConsumer<? super K, ? super V> action) {
1315         Objects.requireNonNull(action);
1316         int expectedModCount = modCount;
1317         for (TreeMapEntry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {
1318             action.accept(e.key, e.value);
1319 
1320             if (expectedModCount != modCount) {
1321                 throw new ConcurrentModificationException();
1322             }
1323         }
1324     }
1325 
1326     @Override
replaceAll(BiFunction<? super K, ? super V, ? extends V> function)1327     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
1328         Objects.requireNonNull(function);
1329         int expectedModCount = modCount;
1330 
1331         for (TreeMapEntry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {
1332             e.value = function.apply(e.key, e.value);
1333 
1334             if (expectedModCount != modCount) {
1335                 throw new ConcurrentModificationException();
1336             }
1337         }
1338     }
1339 
1340     // View class support
1341 
1342     class Values extends AbstractCollection<V> {
iterator()1343         public Iterator<V> iterator() {
1344             return new ValueIterator(getFirstEntry());
1345         }
1346 
size()1347         public int size() {
1348             return TreeMap.this.size();
1349         }
1350 
contains(Object o)1351         public boolean contains(Object o) {
1352             return TreeMap.this.containsValue(o);
1353         }
1354 
remove(Object o)1355         public boolean remove(Object o) {
1356             for (TreeMapEntry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
1357                 if (valEquals(e.getValue(), o)) {
1358                     deleteEntry(e);
1359                     return true;
1360                 }
1361             }
1362             return false;
1363         }
1364 
clear()1365         public void clear() {
1366             TreeMap.this.clear();
1367         }
1368 
spliterator()1369         public Spliterator<V> spliterator() {
1370             return new ValueSpliterator<>(TreeMap.this, null, null, 0, -1, 0);
1371         }
1372     }
1373 
1374     class EntrySet extends AbstractSet<Map.Entry<K,V>> {
iterator()1375         public Iterator<Map.Entry<K,V>> iterator() {
1376             return new EntryIterator(getFirstEntry());
1377         }
1378 
contains(Object o)1379         public boolean contains(Object o) {
1380             if (!(o instanceof Map.Entry<?, ?> entry))
1381                 return false;
1382             Object value = entry.getValue();
1383             TreeMapEntry<K,V> p = getEntry(entry.getKey());
1384             return p != null && valEquals(p.getValue(), value);
1385         }
1386 
remove(Object o)1387         public boolean remove(Object o) {
1388             if (!(o instanceof Map.Entry<?, ?> entry))
1389                 return false;
1390             Object value = entry.getValue();
1391             TreeMapEntry<K,V> p = getEntry(entry.getKey());
1392             if (p != null && valEquals(p.getValue(), value)) {
1393                 deleteEntry(p);
1394                 return true;
1395             }
1396             return false;
1397         }
1398 
size()1399         public int size() {
1400             return TreeMap.this.size();
1401         }
1402 
clear()1403         public void clear() {
1404             TreeMap.this.clear();
1405         }
1406 
spliterator()1407         public Spliterator<Map.Entry<K,V>> spliterator() {
1408             return new EntrySpliterator<>(TreeMap.this, null, null, 0, -1, 0);
1409         }
1410     }
1411 
1412     /*
1413      * Unlike Values and EntrySet, the KeySet class is static,
1414      * delegating to a NavigableMap to allow use by SubMaps, which
1415      * outweighs the ugliness of needing type-tests for the following
1416      * Iterator methods that are defined appropriately in main versus
1417      * submap classes.
1418      */
1419 
keyIterator()1420     Iterator<K> keyIterator() {
1421         return new KeyIterator(getFirstEntry());
1422     }
1423 
descendingKeyIterator()1424     Iterator<K> descendingKeyIterator() {
1425         return new DescendingKeyIterator(getLastEntry());
1426     }
1427 
1428     static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
1429         private final NavigableMap<E, ?> m;
KeySet(NavigableMap<E,?> map)1430         KeySet(NavigableMap<E,?> map) { m = map; }
1431 
iterator()1432         public Iterator<E> iterator() {
1433             if (m instanceof TreeMap)
1434                 return ((TreeMap<E,?>)m).keyIterator();
1435             else
1436                 return ((TreeMap.NavigableSubMap<E,?>)m).keyIterator();
1437         }
1438 
descendingIterator()1439         public Iterator<E> descendingIterator() {
1440             if (m instanceof TreeMap)
1441                 return ((TreeMap<E,?>)m).descendingKeyIterator();
1442             else
1443                 return ((TreeMap.NavigableSubMap<E,?>)m).descendingKeyIterator();
1444         }
1445 
size()1446         public int size() { return m.size(); }
isEmpty()1447         public boolean isEmpty() { return m.isEmpty(); }
contains(Object o)1448         public boolean contains(Object o) { return m.containsKey(o); }
clear()1449         public void clear() { m.clear(); }
lower(E e)1450         public E lower(E e) { return m.lowerKey(e); }
floor(E e)1451         public E floor(E e) { return m.floorKey(e); }
ceiling(E e)1452         public E ceiling(E e) { return m.ceilingKey(e); }
higher(E e)1453         public E higher(E e) { return m.higherKey(e); }
first()1454         public E first() { return m.firstKey(); }
last()1455         public E last() { return m.lastKey(); }
comparator()1456         public Comparator<? super E> comparator() { return m.comparator(); }
pollFirst()1457         public E pollFirst() {
1458             Map.Entry<E,?> e = m.pollFirstEntry();
1459             return (e == null) ? null : e.getKey();
1460         }
pollLast()1461         public E pollLast() {
1462             Map.Entry<E,?> e = m.pollLastEntry();
1463             return (e == null) ? null : e.getKey();
1464         }
remove(Object o)1465         public boolean remove(Object o) {
1466             int oldSize = size();
1467             m.remove(o);
1468             return size() != oldSize;
1469         }
subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)1470         public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
1471                                       E toElement,   boolean toInclusive) {
1472             return new KeySet<>(m.subMap(fromElement, fromInclusive,
1473                                           toElement,   toInclusive));
1474         }
headSet(E toElement, boolean inclusive)1475         public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1476             return new KeySet<>(m.headMap(toElement, inclusive));
1477         }
tailSet(E fromElement, boolean inclusive)1478         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1479             return new KeySet<>(m.tailMap(fromElement, inclusive));
1480         }
subSet(E fromElement, E toElement)1481         public SortedSet<E> subSet(E fromElement, E toElement) {
1482             return subSet(fromElement, true, toElement, false);
1483         }
headSet(E toElement)1484         public SortedSet<E> headSet(E toElement) {
1485             return headSet(toElement, false);
1486         }
tailSet(E fromElement)1487         public SortedSet<E> tailSet(E fromElement) {
1488             return tailSet(fromElement, true);
1489         }
descendingSet()1490         public NavigableSet<E> descendingSet() {
1491             return new KeySet<>(m.descendingMap());
1492         }
1493 
spliterator()1494         public Spliterator<E> spliterator() {
1495             return keySpliteratorFor(m);
1496         }
1497     }
1498 
1499     /**
1500      * Base class for TreeMap Iterators
1501      */
1502     abstract class PrivateEntryIterator<T> implements Iterator<T> {
1503         TreeMapEntry<K,V> next;
1504         TreeMapEntry<K,V> lastReturned;
1505         int expectedModCount;
1506 
PrivateEntryIterator(TreeMapEntry<K,V> first)1507         PrivateEntryIterator(TreeMapEntry<K,V> first) {
1508             expectedModCount = modCount;
1509             lastReturned = null;
1510             next = first;
1511         }
1512 
hasNext()1513         public final boolean hasNext() {
1514             return next != null;
1515         }
1516 
nextEntry()1517         final TreeMapEntry<K,V> nextEntry() {
1518             TreeMapEntry<K,V> e = next;
1519             if (e == null)
1520                 throw new NoSuchElementException();
1521             if (modCount != expectedModCount)
1522                 throw new ConcurrentModificationException();
1523             next = successor(e);
1524             lastReturned = e;
1525             return e;
1526         }
1527 
prevEntry()1528         final TreeMapEntry<K,V> prevEntry() {
1529             TreeMapEntry<K,V> e = next;
1530             if (e == null)
1531                 throw new NoSuchElementException();
1532             if (modCount != expectedModCount)
1533                 throw new ConcurrentModificationException();
1534             next = predecessor(e);
1535             lastReturned = e;
1536             return e;
1537         }
1538 
remove()1539         public void remove() {
1540             if (lastReturned == null)
1541                 throw new IllegalStateException();
1542             if (modCount != expectedModCount)
1543                 throw new ConcurrentModificationException();
1544             // deleted entries are replaced by their successors
1545             if (lastReturned.left != null && lastReturned.right != null)
1546                 next = lastReturned;
1547             deleteEntry(lastReturned);
1548             expectedModCount = modCount;
1549             lastReturned = null;
1550         }
1551     }
1552 
1553     final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
EntryIterator(TreeMapEntry<K,V> first)1554         EntryIterator(TreeMapEntry<K,V> first) {
1555             super(first);
1556         }
next()1557         public Map.Entry<K,V> next() {
1558             return nextEntry();
1559         }
1560     }
1561 
1562     final class ValueIterator extends PrivateEntryIterator<V> {
ValueIterator(TreeMapEntry<K,V> first)1563         ValueIterator(TreeMapEntry<K,V> first) {
1564             super(first);
1565         }
next()1566         public V next() {
1567             return nextEntry().value;
1568         }
1569     }
1570 
1571     final class KeyIterator extends PrivateEntryIterator<K> {
KeyIterator(TreeMapEntry<K,V> first)1572         KeyIterator(TreeMapEntry<K,V> first) {
1573             super(first);
1574         }
next()1575         public K next() {
1576             return nextEntry().key;
1577         }
1578     }
1579 
1580     final class DescendingKeyIterator extends PrivateEntryIterator<K> {
DescendingKeyIterator(TreeMapEntry<K,V> first)1581         DescendingKeyIterator(TreeMapEntry<K,V> first) {
1582             super(first);
1583         }
next()1584         public K next() {
1585             return prevEntry().key;
1586         }
remove()1587         public void remove() {
1588             if (lastReturned == null)
1589                 throw new IllegalStateException();
1590             if (modCount != expectedModCount)
1591                 throw new ConcurrentModificationException();
1592             deleteEntry(lastReturned);
1593             lastReturned = null;
1594             expectedModCount = modCount;
1595         }
1596     }
1597 
1598     // Little utilities
1599 
1600     /**
1601      * Compares two keys using the correct comparison method for this TreeMap.
1602      */
1603     @SuppressWarnings("unchecked")
compare(Object k1, Object k2)1604     final int compare(Object k1, Object k2) {
1605         return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
1606             : comparator.compare((K)k1, (K)k2);
1607     }
1608 
1609     /**
1610      * Test two values for equality.  Differs from o1.equals(o2) only in
1611      * that it copes with {@code null} o1 properly.
1612      */
valEquals(Object o1, Object o2)1613     static final boolean valEquals(Object o1, Object o2) {
1614         return (o1==null ? o2==null : o1.equals(o2));
1615     }
1616 
1617     /**
1618      * Return SimpleImmutableEntry for entry, or null if null
1619      */
exportEntry(TreeMapEntry<K,V> e)1620     static <K,V> Map.Entry<K,V> exportEntry(TreeMapEntry<K,V> e) {
1621         return (e == null) ? null :
1622             new AbstractMap.SimpleImmutableEntry<>(e);
1623     }
1624 
1625     /**
1626      * Return key for entry, or null if null
1627      */
keyOrNull(TreeMapEntry<K,V> e)1628     static <K,V> K keyOrNull(TreeMapEntry<K,V> e) {
1629         return (e == null) ? null : e.key;
1630     }
1631 
1632     /**
1633      * Returns the key corresponding to the specified Entry.
1634      * @throws NoSuchElementException if the Entry is null
1635      */
key(TreeMapEntry<K,?> e)1636     static <K> K key(TreeMapEntry<K,?> e) {
1637         if (e==null)
1638             throw new NoSuchElementException();
1639         return e.key;
1640     }
1641 
1642 
1643     // SubMaps
1644 
1645     /**
1646      * Dummy value serving as unmatchable fence key for unbounded
1647      * SubMapIterators
1648      */
1649     private static final Object UNBOUNDED = new Object();
1650 
1651     /**
1652      * @serial include
1653      */
1654     abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
1655         implements NavigableMap<K,V>, java.io.Serializable {
1656         // Android-changed: Explicitly add a serialVersionUID so that we're serialization.
1657         // compatible with the Java-7 version of this class. Several new methods were added
1658         // in Java-8 but none of them have any bearing on the serialized format of the class
1659         // or require any additional state to be preserved.
1660         @java.io.Serial
1661         private static final long serialVersionUID = 2765629423043303731L;
1662 
1663         /**
1664          * The backing map.
1665          */
1666         final TreeMap<K,V> m;
1667 
1668         /**
1669          * Endpoints are represented as triples (fromStart, lo,
1670          * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
1671          * true, then the low (absolute) bound is the start of the
1672          * backing map, and the other values are ignored. Otherwise,
1673          * if loInclusive is true, lo is the inclusive bound, else lo
1674          * is the exclusive bound. Similarly for the upper bound.
1675          */
1676         @SuppressWarnings("serial") // Conditionally serializable
1677         final K lo;
1678         @SuppressWarnings("serial") // Conditionally serializable
1679         final K hi;
1680         final boolean fromStart, toEnd;
1681         final boolean loInclusive, hiInclusive;
1682 
NavigableSubMap(TreeMap<K,V> m, boolean fromStart, K lo, boolean loInclusive, boolean toEnd, K hi, boolean hiInclusive)1683         NavigableSubMap(TreeMap<K,V> m,
1684                         boolean fromStart, K lo, boolean loInclusive,
1685                         boolean toEnd,     K hi, boolean hiInclusive) {
1686             if (!fromStart && !toEnd) {
1687                 if (m.compare(lo, hi) > 0)
1688                     throw new IllegalArgumentException("fromKey > toKey");
1689             } else {
1690                 if (!fromStart) // type check
1691                     m.compare(lo, lo);
1692                 if (!toEnd)
1693                     m.compare(hi, hi);
1694             }
1695 
1696             this.m = m;
1697             this.fromStart = fromStart;
1698             this.lo = lo;
1699             this.loInclusive = loInclusive;
1700             this.toEnd = toEnd;
1701             this.hi = hi;
1702             this.hiInclusive = hiInclusive;
1703         }
1704 
1705         // internal utilities
1706 
tooLow(Object key)1707         final boolean tooLow(Object key) {
1708             if (!fromStart) {
1709                 int c = m.compare(key, lo);
1710                 if (c < 0 || (c == 0 && !loInclusive))
1711                     return true;
1712             }
1713             return false;
1714         }
1715 
tooHigh(Object key)1716         final boolean tooHigh(Object key) {
1717             if (!toEnd) {
1718                 int c = m.compare(key, hi);
1719                 if (c > 0 || (c == 0 && !hiInclusive))
1720                     return true;
1721             }
1722             return false;
1723         }
1724 
inRange(Object key)1725         final boolean inRange(Object key) {
1726             return !tooLow(key) && !tooHigh(key);
1727         }
1728 
inClosedRange(Object key)1729         final boolean inClosedRange(Object key) {
1730             return (fromStart || m.compare(key, lo) >= 0)
1731                 && (toEnd || m.compare(hi, key) >= 0);
1732         }
1733 
inRange(Object key, boolean inclusive)1734         final boolean inRange(Object key, boolean inclusive) {
1735             return inclusive ? inRange(key) : inClosedRange(key);
1736         }
1737 
1738         /*
1739          * Absolute versions of relation operations.
1740          * Subclasses map to these using like-named "sub"
1741          * versions that invert senses for descending maps
1742          */
1743 
absLowest()1744         final TreeMapEntry<K,V> absLowest() {
1745             TreeMapEntry<K,V> e =
1746                 (fromStart ?  m.getFirstEntry() :
1747                  (loInclusive ? m.getCeilingEntry(lo) :
1748                                 m.getHigherEntry(lo)));
1749             return (e == null || tooHigh(e.key)) ? null : e;
1750         }
1751 
absHighest()1752         final TreeMapEntry<K,V> absHighest() {
1753             TreeMapEntry<K,V> e =
1754                 (toEnd ?  m.getLastEntry() :
1755                  (hiInclusive ?  m.getFloorEntry(hi) :
1756                                  m.getLowerEntry(hi)));
1757             return (e == null || tooLow(e.key)) ? null : e;
1758         }
1759 
absCeiling(K key)1760         final TreeMapEntry<K,V> absCeiling(K key) {
1761             if (tooLow(key))
1762                 return absLowest();
1763             TreeMapEntry<K,V> e = m.getCeilingEntry(key);
1764             return (e == null || tooHigh(e.key)) ? null : e;
1765         }
1766 
absHigher(K key)1767         final TreeMapEntry<K,V> absHigher(K key) {
1768             if (tooLow(key))
1769                 return absLowest();
1770             TreeMapEntry<K,V> e = m.getHigherEntry(key);
1771             return (e == null || tooHigh(e.key)) ? null : e;
1772         }
1773 
absFloor(K key)1774         final TreeMapEntry<K,V> absFloor(K key) {
1775             if (tooHigh(key))
1776                 return absHighest();
1777             TreeMapEntry<K,V> e = m.getFloorEntry(key);
1778             return (e == null || tooLow(e.key)) ? null : e;
1779         }
1780 
absLower(K key)1781         final TreeMapEntry<K,V> absLower(K key) {
1782             if (tooHigh(key))
1783                 return absHighest();
1784             TreeMapEntry<K,V> e = m.getLowerEntry(key);
1785             return (e == null || tooLow(e.key)) ? null : e;
1786         }
1787 
1788         /** Returns the absolute high fence for ascending traversal */
absHighFence()1789         final TreeMapEntry<K,V> absHighFence() {
1790             return (toEnd ? null : (hiInclusive ?
1791                                     m.getHigherEntry(hi) :
1792                                     m.getCeilingEntry(hi)));
1793         }
1794 
1795         /** Return the absolute low fence for descending traversal  */
absLowFence()1796         final TreeMapEntry<K,V> absLowFence() {
1797             return (fromStart ? null : (loInclusive ?
1798                                         m.getLowerEntry(lo) :
1799                                         m.getFloorEntry(lo)));
1800         }
1801 
1802         // Abstract methods defined in ascending vs descending classes
1803         // These relay to the appropriate absolute versions
1804 
subLowest()1805         abstract TreeMapEntry<K,V> subLowest();
subHighest()1806         abstract TreeMapEntry<K,V> subHighest();
subCeiling(K key)1807         abstract TreeMapEntry<K,V> subCeiling(K key);
subHigher(K key)1808         abstract TreeMapEntry<K,V> subHigher(K key);
subFloor(K key)1809         abstract TreeMapEntry<K,V> subFloor(K key);
subLower(K key)1810         abstract TreeMapEntry<K,V> subLower(K key);
1811 
1812         /** Returns ascending iterator from the perspective of this submap */
keyIterator()1813         abstract Iterator<K> keyIterator();
1814 
keySpliterator()1815         abstract Spliterator<K> keySpliterator();
1816 
1817         /** Returns descending iterator from the perspective of this submap */
descendingKeyIterator()1818         abstract Iterator<K> descendingKeyIterator();
1819 
1820         // public methods
1821 
isEmpty()1822         public boolean isEmpty() {
1823             return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty();
1824         }
1825 
size()1826         public int size() {
1827             return (fromStart && toEnd) ? m.size() : entrySet().size();
1828         }
1829 
containsKey(Object key)1830         public final boolean containsKey(Object key) {
1831             return inRange(key) && m.containsKey(key);
1832         }
1833 
put(K key, V value)1834         public final V put(K key, V value) {
1835             if (!inRange(key))
1836                 throw new IllegalArgumentException("key out of range");
1837             return m.put(key, value);
1838         }
1839 
putIfAbsent(K key, V value)1840         public V putIfAbsent(K key, V value) {
1841             if (!inRange(key))
1842                 throw new IllegalArgumentException("key out of range");
1843             return m.putIfAbsent(key, value);
1844         }
1845 
merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)1846         public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
1847             if (!inRange(key))
1848                 throw new IllegalArgumentException("key out of range");
1849             return m.merge(key, value, remappingFunction);
1850         }
1851 
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)1852         public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
1853             if (!inRange(key)) {
1854                 // Do not throw if mapping function returns null
1855                 // to preserve compatibility with default computeIfAbsent implementation
1856                 if (mappingFunction.apply(key) == null) return null;
1857                 throw new IllegalArgumentException("key out of range");
1858             }
1859             return m.computeIfAbsent(key, mappingFunction);
1860         }
1861 
compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1862         public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1863             if (!inRange(key)) {
1864                 // Do not throw if remapping function returns null
1865                 // to preserve compatibility with default computeIfAbsent implementation
1866                 if (remappingFunction.apply(key, null) == null) return null;
1867                 throw new IllegalArgumentException("key out of range");
1868             }
1869             return m.compute(key, remappingFunction);
1870         }
1871 
computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1872         public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1873             return !inRange(key) ? null : m.computeIfPresent(key, remappingFunction);
1874         }
1875 
get(Object key)1876         public final V get(Object key) {
1877             return !inRange(key) ? null :  m.get(key);
1878         }
1879 
remove(Object key)1880         public final V remove(Object key) {
1881             return !inRange(key) ? null : m.remove(key);
1882         }
1883 
ceilingEntry(K key)1884         public final Map.Entry<K,V> ceilingEntry(K key) {
1885             return exportEntry(subCeiling(key));
1886         }
1887 
ceilingKey(K key)1888         public final K ceilingKey(K key) {
1889             return keyOrNull(subCeiling(key));
1890         }
1891 
higherEntry(K key)1892         public final Map.Entry<K,V> higherEntry(K key) {
1893             return exportEntry(subHigher(key));
1894         }
1895 
higherKey(K key)1896         public final K higherKey(K key) {
1897             return keyOrNull(subHigher(key));
1898         }
1899 
floorEntry(K key)1900         public final Map.Entry<K,V> floorEntry(K key) {
1901             return exportEntry(subFloor(key));
1902         }
1903 
floorKey(K key)1904         public final K floorKey(K key) {
1905             return keyOrNull(subFloor(key));
1906         }
1907 
lowerEntry(K key)1908         public final Map.Entry<K,V> lowerEntry(K key) {
1909             return exportEntry(subLower(key));
1910         }
1911 
lowerKey(K key)1912         public final K lowerKey(K key) {
1913             return keyOrNull(subLower(key));
1914         }
1915 
firstKey()1916         public final K firstKey() {
1917             return key(subLowest());
1918         }
1919 
lastKey()1920         public final K lastKey() {
1921             return key(subHighest());
1922         }
1923 
firstEntry()1924         public final Map.Entry<K,V> firstEntry() {
1925             return exportEntry(subLowest());
1926         }
1927 
lastEntry()1928         public final Map.Entry<K,V> lastEntry() {
1929             return exportEntry(subHighest());
1930         }
1931 
pollFirstEntry()1932         public final Map.Entry<K,V> pollFirstEntry() {
1933             TreeMapEntry<K,V> e = subLowest();
1934             Map.Entry<K,V> result = exportEntry(e);
1935             if (e != null)
1936                 m.deleteEntry(e);
1937             return result;
1938         }
1939 
pollLastEntry()1940         public final Map.Entry<K,V> pollLastEntry() {
1941             TreeMapEntry<K,V> e = subHighest();
1942             Map.Entry<K,V> result = exportEntry(e);
1943             if (e != null)
1944                 m.deleteEntry(e);
1945             return result;
1946         }
1947 
1948         // Views
1949         transient NavigableMap<K,V> descendingMapView;
1950         transient EntrySetView entrySetView;
1951         transient KeySet<K> navigableKeySetView;
1952 
navigableKeySet()1953         public final NavigableSet<K> navigableKeySet() {
1954             KeySet<K> nksv = navigableKeySetView;
1955             return (nksv != null) ? nksv :
1956                 (navigableKeySetView = new TreeMap.KeySet<>(this));
1957         }
1958 
keySet()1959         public final Set<K> keySet() {
1960             return navigableKeySet();
1961         }
1962 
descendingKeySet()1963         public NavigableSet<K> descendingKeySet() {
1964             return descendingMap().navigableKeySet();
1965         }
1966 
subMap(K fromKey, K toKey)1967         public final SortedMap<K,V> subMap(K fromKey, K toKey) {
1968             return subMap(fromKey, true, toKey, false);
1969         }
1970 
headMap(K toKey)1971         public final SortedMap<K,V> headMap(K toKey) {
1972             return headMap(toKey, false);
1973         }
1974 
tailMap(K fromKey)1975         public final SortedMap<K,V> tailMap(K fromKey) {
1976             return tailMap(fromKey, true);
1977         }
1978 
1979         // View classes
1980 
1981         abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
1982             private transient int size = -1, sizeModCount;
1983 
size()1984             public int size() {
1985                 if (fromStart && toEnd)
1986                     return m.size();
1987                 if (size == -1 || sizeModCount != m.modCount) {
1988                     sizeModCount = m.modCount;
1989                     size = 0;
1990                     Iterator<?> i = iterator();
1991                     while (i.hasNext()) {
1992                         size++;
1993                         i.next();
1994                     }
1995                 }
1996                 return size;
1997             }
1998 
isEmpty()1999             public boolean isEmpty() {
2000                 TreeMapEntry<K,V> n = absLowest();
2001                 return n == null || tooHigh(n.key);
2002             }
2003 
contains(Object o)2004             public boolean contains(Object o) {
2005                 if (!(o instanceof Entry<?, ?> entry))
2006                     return false;
2007                 Object key = entry.getKey();
2008                 if (!inRange(key))
2009                     return false;
2010                 TreeMapEntry<?, ?> node = m.getEntry(key);
2011                 return node != null &&
2012                     valEquals(node.getValue(), entry.getValue());
2013             }
2014 
remove(Object o)2015             public boolean remove(Object o) {
2016                 if (!(o instanceof Entry<?, ?> entry))
2017                     return false;
2018                 Object key = entry.getKey();
2019                 if (!inRange(key))
2020                     return false;
2021                 TreeMapEntry<K,V> node = m.getEntry(key);
2022                 if (node!=null && valEquals(node.getValue(),
2023                                             entry.getValue())) {
2024                     m.deleteEntry(node);
2025                     return true;
2026                 }
2027                 return false;
2028             }
2029         }
2030 
2031         /**
2032          * Iterators for SubMaps
2033          */
2034         abstract class SubMapIterator<T> implements Iterator<T> {
2035             TreeMapEntry<K,V> lastReturned;
2036             TreeMapEntry<K,V> next;
2037             final Object fenceKey;
2038             int expectedModCount;
2039 
SubMapIterator(TreeMapEntry<K,V> first, TreeMapEntry<K,V> fence)2040             SubMapIterator(TreeMapEntry<K,V> first,
2041                            TreeMapEntry<K,V> fence) {
2042                 expectedModCount = m.modCount;
2043                 lastReturned = null;
2044                 next = first;
2045                 fenceKey = fence == null ? UNBOUNDED : fence.key;
2046             }
2047 
hasNext()2048             public final boolean hasNext() {
2049                 return next != null && next.key != fenceKey;
2050             }
2051 
nextEntry()2052             final TreeMapEntry<K,V> nextEntry() {
2053                 TreeMapEntry<K,V> e = next;
2054                 if (e == null || e.key == fenceKey)
2055                     throw new NoSuchElementException();
2056                 if (m.modCount != expectedModCount)
2057                     throw new ConcurrentModificationException();
2058                 next = successor(e);
2059                 lastReturned = e;
2060                 return e;
2061             }
2062 
prevEntry()2063             final TreeMapEntry<K,V> prevEntry() {
2064                 TreeMapEntry<K,V> e = next;
2065                 if (e == null || e.key == fenceKey)
2066                     throw new NoSuchElementException();
2067                 if (m.modCount != expectedModCount)
2068                     throw new ConcurrentModificationException();
2069                 next = predecessor(e);
2070                 lastReturned = e;
2071                 return e;
2072             }
2073 
removeAscending()2074             final void removeAscending() {
2075                 if (lastReturned == null)
2076                     throw new IllegalStateException();
2077                 if (m.modCount != expectedModCount)
2078                     throw new ConcurrentModificationException();
2079                 // deleted entries are replaced by their successors
2080                 if (lastReturned.left != null && lastReturned.right != null)
2081                     next = lastReturned;
2082                 m.deleteEntry(lastReturned);
2083                 lastReturned = null;
2084                 expectedModCount = m.modCount;
2085             }
2086 
removeDescending()2087             final void removeDescending() {
2088                 if (lastReturned == null)
2089                     throw new IllegalStateException();
2090                 if (m.modCount != expectedModCount)
2091                     throw new ConcurrentModificationException();
2092                 m.deleteEntry(lastReturned);
2093                 lastReturned = null;
2094                 expectedModCount = m.modCount;
2095             }
2096 
2097         }
2098 
2099         final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
SubMapEntryIterator(TreeMapEntry<K,V> first, TreeMapEntry<K,V> fence)2100             SubMapEntryIterator(TreeMapEntry<K,V> first,
2101                                 TreeMapEntry<K,V> fence) {
2102                 super(first, fence);
2103             }
next()2104             public Map.Entry<K,V> next() {
2105                 return nextEntry();
2106             }
remove()2107             public void remove() {
2108                 removeAscending();
2109             }
2110         }
2111 
2112         final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
DescendingSubMapEntryIterator(TreeMapEntry<K,V> last, TreeMapEntry<K,V> fence)2113             DescendingSubMapEntryIterator(TreeMapEntry<K,V> last,
2114                                           TreeMapEntry<K,V> fence) {
2115                 super(last, fence);
2116             }
2117 
next()2118             public Map.Entry<K,V> next() {
2119                 return prevEntry();
2120             }
remove()2121             public void remove() {
2122                 removeDescending();
2123             }
2124         }
2125 
2126         // Implement minimal Spliterator as KeySpliterator backup
2127         final class SubMapKeyIterator extends SubMapIterator<K>
2128             implements Spliterator<K> {
SubMapKeyIterator(TreeMapEntry<K,V> first, TreeMapEntry<K,V> fence)2129             SubMapKeyIterator(TreeMapEntry<K,V> first,
2130                               TreeMapEntry<K,V> fence) {
2131                 super(first, fence);
2132             }
next()2133             public K next() {
2134                 return nextEntry().key;
2135             }
remove()2136             public void remove() {
2137                 removeAscending();
2138             }
trySplit()2139             public Spliterator<K> trySplit() {
2140                 return null;
2141             }
forEachRemaining(Consumer<? super K> action)2142             public void forEachRemaining(Consumer<? super K> action) {
2143                 while (hasNext())
2144                     action.accept(next());
2145             }
tryAdvance(Consumer<? super K> action)2146             public boolean tryAdvance(Consumer<? super K> action) {
2147                 if (hasNext()) {
2148                     action.accept(next());
2149                     return true;
2150                 }
2151                 return false;
2152             }
estimateSize()2153             public long estimateSize() {
2154                 return Long.MAX_VALUE;
2155             }
characteristics()2156             public int characteristics() {
2157                 return Spliterator.DISTINCT | Spliterator.ORDERED |
2158                     Spliterator.SORTED;
2159             }
getComparator()2160             public final Comparator<? super K>  getComparator() {
2161                 return NavigableSubMap.this.comparator();
2162             }
2163         }
2164 
2165         final class DescendingSubMapKeyIterator extends SubMapIterator<K>
2166             implements Spliterator<K> {
DescendingSubMapKeyIterator(TreeMapEntry<K,V> last, TreeMapEntry<K,V> fence)2167             DescendingSubMapKeyIterator(TreeMapEntry<K,V> last,
2168                                         TreeMapEntry<K,V> fence) {
2169                 super(last, fence);
2170             }
next()2171             public K next() {
2172                 return prevEntry().key;
2173             }
remove()2174             public void remove() {
2175                 removeDescending();
2176             }
trySplit()2177             public Spliterator<K> trySplit() {
2178                 return null;
2179             }
forEachRemaining(Consumer<? super K> action)2180             public void forEachRemaining(Consumer<? super K> action) {
2181                 while (hasNext())
2182                     action.accept(next());
2183             }
tryAdvance(Consumer<? super K> action)2184             public boolean tryAdvance(Consumer<? super K> action) {
2185                 if (hasNext()) {
2186                     action.accept(next());
2187                     return true;
2188                 }
2189                 return false;
2190             }
estimateSize()2191             public long estimateSize() {
2192                 return Long.MAX_VALUE;
2193             }
characteristics()2194             public int characteristics() {
2195                 return Spliterator.DISTINCT | Spliterator.ORDERED;
2196             }
2197         }
2198     }
2199 
2200     /**
2201      * @serial include
2202      */
2203     static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
2204         @java.io.Serial
2205         private static final long serialVersionUID = 912986545866124060L;
2206 
AscendingSubMap(TreeMap<K,V> m, boolean fromStart, K lo, boolean loInclusive, boolean toEnd, K hi, boolean hiInclusive)2207         AscendingSubMap(TreeMap<K,V> m,
2208                         boolean fromStart, K lo, boolean loInclusive,
2209                         boolean toEnd,     K hi, boolean hiInclusive) {
2210             super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
2211         }
2212 
comparator()2213         public Comparator<? super K> comparator() {
2214             return m.comparator();
2215         }
2216 
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)2217         public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
2218                                         K toKey,   boolean toInclusive) {
2219             if (!inRange(fromKey, fromInclusive))
2220                 throw new IllegalArgumentException("fromKey out of range");
2221             if (!inRange(toKey, toInclusive))
2222                 throw new IllegalArgumentException("toKey out of range");
2223             return new AscendingSubMap<>(m,
2224                                          false, fromKey, fromInclusive,
2225                                          false, toKey,   toInclusive);
2226         }
2227 
headMap(K toKey, boolean inclusive)2228         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
2229             // BEGIN Android-changed: Fix for edge cases.
2230             // if (!inRange(toKey, inclusive))
2231             if (!inRange(toKey) && !(!toEnd && m.compare(toKey, hi) == 0 &&
2232                 !hiInclusive && !inclusive))
2233             // END Android-changed: Fix for edge cases.
2234                 throw new IllegalArgumentException("toKey out of range");
2235             return new AscendingSubMap<>(m,
2236                                          fromStart, lo,    loInclusive,
2237                                          false,     toKey, inclusive);
2238         }
2239 
tailMap(K fromKey, boolean inclusive)2240         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
2241             // BEGIN Android-changed: Fix for edge cases.
2242             // if (!inRange(fromKey, inclusive))
2243             if (!inRange(fromKey) && !(!fromStart && m.compare(fromKey, lo) == 0 &&
2244                 !loInclusive && !inclusive))
2245             // END Android-changed: Fix for edge cases.
2246                 throw new IllegalArgumentException("fromKey out of range");
2247             return new AscendingSubMap<>(m,
2248                                          false, fromKey, inclusive,
2249                                          toEnd, hi,      hiInclusive);
2250         }
2251 
descendingMap()2252         public NavigableMap<K,V> descendingMap() {
2253             NavigableMap<K,V> mv = descendingMapView;
2254             return (mv != null) ? mv :
2255                 (descendingMapView =
2256                  new DescendingSubMap<>(m,
2257                                         fromStart, lo, loInclusive,
2258                                         toEnd,     hi, hiInclusive));
2259         }
2260 
keyIterator()2261         Iterator<K> keyIterator() {
2262             return new SubMapKeyIterator(absLowest(), absHighFence());
2263         }
2264 
keySpliterator()2265         Spliterator<K> keySpliterator() {
2266             return new SubMapKeyIterator(absLowest(), absHighFence());
2267         }
2268 
descendingKeyIterator()2269         Iterator<K> descendingKeyIterator() {
2270             return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
2271         }
2272 
2273         final class AscendingEntrySetView extends EntrySetView {
iterator()2274             public Iterator<Map.Entry<K,V>> iterator() {
2275                 return new SubMapEntryIterator(absLowest(), absHighFence());
2276             }
2277         }
2278 
entrySet()2279         public Set<Map.Entry<K,V>> entrySet() {
2280             EntrySetView es = entrySetView;
2281             return (es != null) ? es : (entrySetView = new AscendingEntrySetView());
2282         }
2283 
subLowest()2284         TreeMapEntry<K,V> subLowest()       { return absLowest(); }
subHighest()2285         TreeMapEntry<K,V> subHighest()      { return absHighest(); }
subCeiling(K key)2286         TreeMapEntry<K,V> subCeiling(K key) { return absCeiling(key); }
subHigher(K key)2287         TreeMapEntry<K,V> subHigher(K key)  { return absHigher(key); }
subFloor(K key)2288         TreeMapEntry<K,V> subFloor(K key)   { return absFloor(key); }
subLower(K key)2289         TreeMapEntry<K,V> subLower(K key)   { return absLower(key); }
2290     }
2291 
2292     /**
2293      * @serial include
2294      */
2295     static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> {
2296         @java.io.Serial
2297         private static final long serialVersionUID = 912986545866120460L;
DescendingSubMap(TreeMap<K,V> m, boolean fromStart, K lo, boolean loInclusive, boolean toEnd, K hi, boolean hiInclusive)2298         DescendingSubMap(TreeMap<K,V> m,
2299                         boolean fromStart, K lo, boolean loInclusive,
2300                         boolean toEnd,     K hi, boolean hiInclusive) {
2301             super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
2302         }
2303 
2304         @SuppressWarnings("serial") // Conditionally serializable
2305         private final Comparator<? super K> reverseComparator =
2306             Collections.reverseOrder(m.comparator);
2307 
comparator()2308         public Comparator<? super K> comparator() {
2309             return reverseComparator;
2310         }
2311 
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)2312         public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
2313                                         K toKey,   boolean toInclusive) {
2314             if (!inRange(fromKey, fromInclusive))
2315                 throw new IllegalArgumentException("fromKey out of range");
2316             if (!inRange(toKey, toInclusive))
2317                 throw new IllegalArgumentException("toKey out of range");
2318             return new DescendingSubMap<>(m,
2319                                           false, toKey,   toInclusive,
2320                                           false, fromKey, fromInclusive);
2321         }
2322 
headMap(K toKey, boolean inclusive)2323         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
2324             // BEGIN Android-changed: Fix for edge cases.
2325             // if (!inRange(toKey, inclusive))
2326             if (!inRange(toKey) && !(!fromStart && m.compare(toKey, lo) == 0 &&
2327                 !loInclusive && !inclusive))
2328             // END Android-changed: Fix for edge cases.
2329                 throw new IllegalArgumentException("toKey out of range");
2330             return new DescendingSubMap<>(m,
2331                                           false, toKey, inclusive,
2332                                           toEnd, hi,    hiInclusive);
2333         }
2334 
tailMap(K fromKey, boolean inclusive)2335         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
2336             // BEGIN Android-changed: Fix for edge cases.
2337             // if (!inRange(fromKey, inclusive))
2338             if (!inRange(fromKey) && !(!toEnd && m.compare(fromKey, hi) == 0 &&
2339                 !hiInclusive && !inclusive))
2340             // END Android-changed: Fix for edge cases.
2341                 throw new IllegalArgumentException("fromKey out of range");
2342             return new DescendingSubMap<>(m,
2343                                           fromStart, lo, loInclusive,
2344                                           false, fromKey, inclusive);
2345         }
2346 
descendingMap()2347         public NavigableMap<K,V> descendingMap() {
2348             NavigableMap<K,V> mv = descendingMapView;
2349             return (mv != null) ? mv :
2350                 (descendingMapView =
2351                  new AscendingSubMap<>(m,
2352                                        fromStart, lo, loInclusive,
2353                                        toEnd,     hi, hiInclusive));
2354         }
2355 
keyIterator()2356         Iterator<K> keyIterator() {
2357             return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
2358         }
2359 
keySpliterator()2360         Spliterator<K> keySpliterator() {
2361             return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
2362         }
2363 
descendingKeyIterator()2364         Iterator<K> descendingKeyIterator() {
2365             return new SubMapKeyIterator(absLowest(), absHighFence());
2366         }
2367 
2368         final class DescendingEntrySetView extends EntrySetView {
iterator()2369             public Iterator<Map.Entry<K,V>> iterator() {
2370                 return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
2371             }
2372         }
2373 
entrySet()2374         public Set<Map.Entry<K,V>> entrySet() {
2375             EntrySetView es = entrySetView;
2376             return (es != null) ? es : (entrySetView = new DescendingEntrySetView());
2377         }
2378 
subLowest()2379         TreeMapEntry<K,V> subLowest()       { return absHighest(); }
subHighest()2380         TreeMapEntry<K,V> subHighest()      { return absLowest(); }
subCeiling(K key)2381         TreeMapEntry<K,V> subCeiling(K key) { return absFloor(key); }
subHigher(K key)2382         TreeMapEntry<K,V> subHigher(K key)  { return absLower(key); }
subFloor(K key)2383         TreeMapEntry<K,V> subFloor(K key)   { return absCeiling(key); }
subLower(K key)2384         TreeMapEntry<K,V> subLower(K key)   { return absHigher(key); }
2385     }
2386 
2387     /**
2388      * This class exists solely for the sake of serialization
2389      * compatibility with previous releases of TreeMap that did not
2390      * support NavigableMap.  It translates an old-version SubMap into
2391      * a new-version AscendingSubMap. This class is never otherwise
2392      * used.
2393      *
2394      * @serial include
2395      */
2396     private class SubMap extends AbstractMap<K,V>
2397         implements SortedMap<K,V>, java.io.Serializable {
2398         @java.io.Serial
2399         private static final long serialVersionUID = -6520786458950516097L;
2400         private boolean fromStart = false, toEnd = false;
2401         @SuppressWarnings("serial") // Conditionally serializable
2402         private K fromKey;
2403         @SuppressWarnings("serial") // Conditionally serializable
2404         private K toKey;
2405         @java.io.Serial
readResolve()2406         private Object readResolve() {
2407             return new AscendingSubMap<>(TreeMap.this,
2408                                          fromStart, fromKey, true,
2409                                          toEnd, toKey, false);
2410         }
entrySet()2411         public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); }
lastKey()2412         public K lastKey() { throw new InternalError(); }
firstKey()2413         public K firstKey() { throw new InternalError(); }
subMap(K fromKey, K toKey)2414         public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); }
headMap(K toKey)2415         public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); }
tailMap(K fromKey)2416         public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); }
comparator()2417         public Comparator<? super K> comparator() { throw new InternalError(); }
2418     }
2419 
2420 
2421     // Red-black mechanics
2422 
2423     private static final boolean RED   = false;
2424     private static final boolean BLACK = true;
2425 
2426     /**
2427      * Node in the Tree.  Doubles as a means to pass key-value pairs back to
2428      * user (see Map.Entry).
2429      */
2430     // BEGIN Android-changed: Renamed Entry -> TreeMapEntry.
2431     // Code references to "TreeMap.Entry" must mean Map.Entry
2432     //
2433     // This mirrors the corresponding rename of LinkedHashMap's
2434     // Entry->LinkedHashMapEntry.
2435     //
2436     // This is for source compatibility with earlier versions of Android.
2437     // Otherwise, it would hide Map.Entry.
2438     // END Android-changed: Renamed Entry -> TreeMapEntry.
2439     static final class TreeMapEntry<K,V> implements Map.Entry<K,V> {
2440         K key;
2441         V value;
2442         TreeMapEntry<K,V> left;
2443         TreeMapEntry<K,V> right;
2444         TreeMapEntry<K,V> parent;
2445         boolean color = BLACK;
2446 
2447         /**
2448          * Make a new cell with given key, value, and parent, and with
2449          * {@code null} child links, and BLACK color.
2450          */
TreeMapEntry(K key, V value, TreeMapEntry<K,V> parent)2451         TreeMapEntry(K key, V value, TreeMapEntry<K,V> parent) {
2452             this.key = key;
2453             this.value = value;
2454             this.parent = parent;
2455         }
2456 
2457         /**
2458          * Returns the key.
2459          *
2460          * @return the key
2461          */
getKey()2462         public K getKey() {
2463             return key;
2464         }
2465 
2466         /**
2467          * Returns the value associated with the key.
2468          *
2469          * @return the value associated with the key
2470          */
getValue()2471         public V getValue() {
2472             return value;
2473         }
2474 
2475         /**
2476          * Replaces the value currently associated with the key with the given
2477          * value.
2478          *
2479          * @return the value associated with the key before this method was
2480          *         called
2481          */
setValue(V value)2482         public V setValue(V value) {
2483             V oldValue = this.value;
2484             this.value = value;
2485             return oldValue;
2486         }
2487 
equals(Object o)2488         public boolean equals(Object o) {
2489             return o instanceof Map.Entry<?, ?> e
2490                     && valEquals(key,e.getKey())
2491                     && valEquals(value,e.getValue());
2492         }
2493 
hashCode()2494         public int hashCode() {
2495             int keyHash = (key==null ? 0 : key.hashCode());
2496             int valueHash = (value==null ? 0 : value.hashCode());
2497             return keyHash ^ valueHash;
2498         }
2499 
toString()2500         public String toString() {
2501             return key + "=" + value;
2502         }
2503     }
2504 
2505     /**
2506      * Returns the first Entry in the TreeMap (according to the TreeMap's
2507      * key-sort function).  Returns null if the TreeMap is empty.
2508      */
getFirstEntry()2509     final TreeMapEntry<K,V> getFirstEntry() {
2510         TreeMapEntry<K,V> p = root;
2511         if (p != null)
2512             while (p.left != null)
2513                 p = p.left;
2514         return p;
2515     }
2516 
2517     /**
2518      * Returns the last Entry in the TreeMap (according to the TreeMap's
2519      * key-sort function).  Returns null if the TreeMap is empty.
2520      */
getLastEntry()2521     final TreeMapEntry<K,V> getLastEntry() {
2522         TreeMapEntry<K,V> p = root;
2523         if (p != null)
2524             while (p.right != null)
2525                 p = p.right;
2526         return p;
2527     }
2528 
2529     /**
2530      * Returns the successor of the specified Entry, or null if no such.
2531      */
successor(TreeMapEntry<K,V> t)2532     static <K,V> TreeMapEntry<K,V> successor(TreeMapEntry<K,V> t) {
2533         if (t == null)
2534             return null;
2535         else if (t.right != null) {
2536             TreeMapEntry<K,V> p = t.right;
2537             while (p.left != null)
2538                 p = p.left;
2539             return p;
2540         } else {
2541             TreeMapEntry<K,V> p = t.parent;
2542             TreeMapEntry<K,V> ch = t;
2543             while (p != null && ch == p.right) {
2544                 ch = p;
2545                 p = p.parent;
2546             }
2547             return p;
2548         }
2549     }
2550 
2551     /**
2552      * Returns the predecessor of the specified Entry, or null if no such.
2553      */
predecessor(TreeMapEntry<K,V> t)2554     static <K,V> TreeMapEntry<K,V> predecessor(TreeMapEntry<K,V> t) {
2555         if (t == null)
2556             return null;
2557         else if (t.left != null) {
2558             TreeMapEntry<K,V> p = t.left;
2559             while (p.right != null)
2560                 p = p.right;
2561             return p;
2562         } else {
2563             TreeMapEntry<K,V> p = t.parent;
2564             TreeMapEntry<K,V> ch = t;
2565             while (p != null && ch == p.left) {
2566                 ch = p;
2567                 p = p.parent;
2568             }
2569             return p;
2570         }
2571     }
2572 
2573     /**
2574      * Balancing operations.
2575      *
2576      * Implementations of rebalancings during insertion and deletion are
2577      * slightly different than the CLR version.  Rather than using dummy
2578      * nilnodes, we use a set of accessors that deal properly with null.  They
2579      * are used to avoid messiness surrounding nullness checks in the main
2580      * algorithms.
2581      */
2582 
colorOf(TreeMapEntry<K,V> p)2583     private static <K,V> boolean colorOf(TreeMapEntry<K,V> p) {
2584         return (p == null ? BLACK : p.color);
2585     }
2586 
parentOf(TreeMapEntry<K,V> p)2587     private static <K,V> TreeMapEntry<K,V> parentOf(TreeMapEntry<K,V> p) {
2588         return (p == null ? null: p.parent);
2589     }
2590 
setColor(TreeMapEntry<K,V> p, boolean c)2591     private static <K,V> void setColor(TreeMapEntry<K,V> p, boolean c) {
2592         if (p != null)
2593             p.color = c;
2594     }
2595 
leftOf(TreeMapEntry<K,V> p)2596     private static <K,V> TreeMapEntry<K,V> leftOf(TreeMapEntry<K,V> p) {
2597         return (p == null) ? null: p.left;
2598     }
2599 
rightOf(TreeMapEntry<K,V> p)2600     private static <K,V> TreeMapEntry<K,V> rightOf(TreeMapEntry<K,V> p) {
2601         return (p == null) ? null: p.right;
2602     }
2603 
2604     /** From CLR */
rotateLeft(TreeMapEntry<K,V> p)2605     private void rotateLeft(TreeMapEntry<K,V> p) {
2606         if (p != null) {
2607             TreeMapEntry<K,V> r = p.right;
2608             p.right = r.left;
2609             if (r.left != null)
2610                 r.left.parent = p;
2611             r.parent = p.parent;
2612             if (p.parent == null)
2613                 root = r;
2614             else if (p.parent.left == p)
2615                 p.parent.left = r;
2616             else
2617                 p.parent.right = r;
2618             r.left = p;
2619             p.parent = r;
2620         }
2621     }
2622 
2623     /** From CLR */
rotateRight(TreeMapEntry<K,V> p)2624     private void rotateRight(TreeMapEntry<K,V> p) {
2625         if (p != null) {
2626             TreeMapEntry<K,V> l = p.left;
2627             p.left = l.right;
2628             if (l.right != null) l.right.parent = p;
2629             l.parent = p.parent;
2630             if (p.parent == null)
2631                 root = l;
2632             else if (p.parent.right == p)
2633                 p.parent.right = l;
2634             else p.parent.left = l;
2635             l.right = p;
2636             p.parent = l;
2637         }
2638     }
2639 
2640     /** From CLR */
fixAfterInsertion(TreeMapEntry<K,V> x)2641     private void fixAfterInsertion(TreeMapEntry<K,V> x) {
2642         x.color = RED;
2643 
2644         while (x != null && x != root && x.parent.color == RED) {
2645             if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
2646                 TreeMapEntry<K,V> y = rightOf(parentOf(parentOf(x)));
2647                 if (colorOf(y) == RED) {
2648                     setColor(parentOf(x), BLACK);
2649                     setColor(y, BLACK);
2650                     setColor(parentOf(parentOf(x)), RED);
2651                     x = parentOf(parentOf(x));
2652                 } else {
2653                     if (x == rightOf(parentOf(x))) {
2654                         x = parentOf(x);
2655                         rotateLeft(x);
2656                     }
2657                     setColor(parentOf(x), BLACK);
2658                     setColor(parentOf(parentOf(x)), RED);
2659                     rotateRight(parentOf(parentOf(x)));
2660                 }
2661             } else {
2662                 TreeMapEntry<K,V> y = leftOf(parentOf(parentOf(x)));
2663                 if (colorOf(y) == RED) {
2664                     setColor(parentOf(x), BLACK);
2665                     setColor(y, BLACK);
2666                     setColor(parentOf(parentOf(x)), RED);
2667                     x = parentOf(parentOf(x));
2668                 } else {
2669                     if (x == leftOf(parentOf(x))) {
2670                         x = parentOf(x);
2671                         rotateRight(x);
2672                     }
2673                     setColor(parentOf(x), BLACK);
2674                     setColor(parentOf(parentOf(x)), RED);
2675                     rotateLeft(parentOf(parentOf(x)));
2676                 }
2677             }
2678         }
2679         root.color = BLACK;
2680     }
2681 
2682     /**
2683      * Delete node p, and then rebalance the tree.
2684      */
deleteEntry(TreeMapEntry<K,V> p)2685     private void deleteEntry(TreeMapEntry<K,V> p) {
2686         modCount++;
2687         size--;
2688 
2689         // If strictly internal, copy successor's element to p and then make p
2690         // point to successor.
2691         if (p.left != null && p.right != null) {
2692             TreeMapEntry<K,V> s = successor(p);
2693             p.key = s.key;
2694             p.value = s.value;
2695             p = s;
2696         } // p has 2 children
2697 
2698         // Start fixup at replacement node, if it exists.
2699         TreeMapEntry<K,V> replacement = (p.left != null ? p.left : p.right);
2700 
2701         if (replacement != null) {
2702             // Link replacement to parent
2703             replacement.parent = p.parent;
2704             if (p.parent == null)
2705                 root = replacement;
2706             else if (p == p.parent.left)
2707                 p.parent.left  = replacement;
2708             else
2709                 p.parent.right = replacement;
2710 
2711             // Null out links so they are OK to use by fixAfterDeletion.
2712             p.left = p.right = p.parent = null;
2713 
2714             // Fix replacement
2715             if (p.color == BLACK)
2716                 fixAfterDeletion(replacement);
2717         } else if (p.parent == null) { // return if we are the only node.
2718             root = null;
2719         } else { //  No children. Use self as phantom replacement and unlink.
2720             if (p.color == BLACK)
2721                 fixAfterDeletion(p);
2722 
2723             if (p.parent != null) {
2724                 if (p == p.parent.left)
2725                     p.parent.left = null;
2726                 else if (p == p.parent.right)
2727                     p.parent.right = null;
2728                 p.parent = null;
2729             }
2730         }
2731     }
2732 
2733     /** From CLR */
fixAfterDeletion(TreeMapEntry<K,V> x)2734     private void fixAfterDeletion(TreeMapEntry<K,V> x) {
2735         while (x != root && colorOf(x) == BLACK) {
2736             if (x == leftOf(parentOf(x))) {
2737                 TreeMapEntry<K,V> sib = rightOf(parentOf(x));
2738 
2739                 if (colorOf(sib) == RED) {
2740                     setColor(sib, BLACK);
2741                     setColor(parentOf(x), RED);
2742                     rotateLeft(parentOf(x));
2743                     sib = rightOf(parentOf(x));
2744                 }
2745 
2746                 if (colorOf(leftOf(sib))  == BLACK &&
2747                     colorOf(rightOf(sib)) == BLACK) {
2748                     setColor(sib, RED);
2749                     x = parentOf(x);
2750                 } else {
2751                     if (colorOf(rightOf(sib)) == BLACK) {
2752                         setColor(leftOf(sib), BLACK);
2753                         setColor(sib, RED);
2754                         rotateRight(sib);
2755                         sib = rightOf(parentOf(x));
2756                     }
2757                     setColor(sib, colorOf(parentOf(x)));
2758                     setColor(parentOf(x), BLACK);
2759                     setColor(rightOf(sib), BLACK);
2760                     rotateLeft(parentOf(x));
2761                     x = root;
2762                 }
2763             } else { // symmetric
2764                 TreeMapEntry<K,V> sib = leftOf(parentOf(x));
2765 
2766                 if (colorOf(sib) == RED) {
2767                     setColor(sib, BLACK);
2768                     setColor(parentOf(x), RED);
2769                     rotateRight(parentOf(x));
2770                     sib = leftOf(parentOf(x));
2771                 }
2772 
2773                 if (colorOf(rightOf(sib)) == BLACK &&
2774                     colorOf(leftOf(sib)) == BLACK) {
2775                     setColor(sib, RED);
2776                     x = parentOf(x);
2777                 } else {
2778                     if (colorOf(leftOf(sib)) == BLACK) {
2779                         setColor(rightOf(sib), BLACK);
2780                         setColor(sib, RED);
2781                         rotateLeft(sib);
2782                         sib = leftOf(parentOf(x));
2783                     }
2784                     setColor(sib, colorOf(parentOf(x)));
2785                     setColor(parentOf(x), BLACK);
2786                     setColor(leftOf(sib), BLACK);
2787                     rotateRight(parentOf(x));
2788                     x = root;
2789                 }
2790             }
2791         }
2792 
2793         setColor(x, BLACK);
2794     }
2795 
2796     @java.io.Serial
2797     private static final long serialVersionUID = 919286545866124006L;
2798 
2799     /**
2800      * Save the state of the {@code TreeMap} instance to a stream (i.e.,
2801      * serialize it).
2802      *
2803      * @serialData The <em>size</em> of the TreeMap (the number of key-value
2804      *             mappings) is emitted (int), followed by the key (Object)
2805      *             and value (Object) for each key-value mapping represented
2806      *             by the TreeMap. The key-value mappings are emitted in
2807      *             key-order (as determined by the TreeMap's Comparator,
2808      *             or by the keys' natural ordering if the TreeMap has no
2809      *             Comparator).
2810      */
2811     @java.io.Serial
writeObject(java.io.ObjectOutputStream s)2812     private void writeObject(java.io.ObjectOutputStream s)
2813         throws java.io.IOException {
2814         // Write out the Comparator and any hidden stuff
2815         s.defaultWriteObject();
2816 
2817         // Write out size (number of Mappings)
2818         s.writeInt(size);
2819 
2820         // Write out keys and values (alternating)
2821         for (Map.Entry<K, V> e : entrySet()) {
2822             s.writeObject(e.getKey());
2823             s.writeObject(e.getValue());
2824         }
2825     }
2826 
2827     /**
2828      * Reconstitute the {@code TreeMap} instance from a stream (i.e.,
2829      * deserialize it).
2830      */
2831     @java.io.Serial
readObject(final java.io.ObjectInputStream s)2832     private void readObject(final java.io.ObjectInputStream s)
2833         throws java.io.IOException, ClassNotFoundException {
2834         // Read in the Comparator and any hidden stuff
2835         s.defaultReadObject();
2836 
2837         // Read in size
2838         int size = s.readInt();
2839 
2840         buildFromSorted(size, null, s, null);
2841     }
2842 
2843     /** Intended to be called only from TreeSet.readObject */
readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)2844     void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
2845         throws java.io.IOException, ClassNotFoundException {
2846         buildFromSorted(size, null, s, defaultVal);
2847     }
2848 
2849     /** Intended to be called only from TreeSet.addAll */
addAllForTreeSet(SortedSet<? extends K> set, V defaultVal)2850     void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
2851         try {
2852             buildFromSorted(set.size(), set.iterator(), null, defaultVal);
2853         } catch (java.io.IOException | ClassNotFoundException cannotHappen) {
2854         }
2855     }
2856 
2857 
2858     /**
2859      * Linear time tree building algorithm from sorted data.  Can accept keys
2860      * and/or values from iterator or stream. This leads to too many
2861      * parameters, but seems better than alternatives.  The four formats
2862      * that this method accepts are:
2863      *
2864      *    1) An iterator of Map.Entries.  (it != null, defaultVal == null).
2865      *    2) An iterator of keys.         (it != null, defaultVal != null).
2866      *    3) A stream of alternating serialized keys and values.
2867      *                                   (it == null, defaultVal == null).
2868      *    4) A stream of serialized keys. (it == null, defaultVal != null).
2869      *
2870      * It is assumed that the comparator of the TreeMap is already set prior
2871      * to calling this method.
2872      *
2873      * @param size the number of keys (or key-value pairs) to be read from
2874      *        the iterator or stream
2875      * @param it If non-null, new entries are created from entries
2876      *        or keys read from this iterator.
2877      * @param str If non-null, new entries are created from keys and
2878      *        possibly values read from this stream in serialized form.
2879      *        Exactly one of it and str should be non-null.
2880      * @param defaultVal if non-null, this default value is used for
2881      *        each value in the map.  If null, each value is read from
2882      *        iterator or stream, as described above.
2883      * @throws java.io.IOException propagated from stream reads. This cannot
2884      *         occur if str is null.
2885      * @throws ClassNotFoundException propagated from readObject.
2886      *         This cannot occur if str is null.
2887      */
buildFromSorted(int size, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal)2888     private void buildFromSorted(int size, Iterator<?> it,
2889                                  java.io.ObjectInputStream str,
2890                                  V defaultVal)
2891         throws  java.io.IOException, ClassNotFoundException {
2892         this.size = size;
2893         root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
2894                                it, str, defaultVal);
2895     }
2896 
2897     /**
2898      * Recursive "helper method" that does the real work of the
2899      * previous method.  Identically named parameters have
2900      * identical definitions.  Additional parameters are documented below.
2901      * It is assumed that the comparator and size fields of the TreeMap are
2902      * already set prior to calling this method.  (It ignores both fields.)
2903      *
2904      * @param level the current level of tree. Initial call should be 0.
2905      * @param lo the first element index of this subtree. Initial should be 0.
2906      * @param hi the last element index of this subtree.  Initial should be
2907      *        size-1.
2908      * @param redLevel the level at which nodes should be red.
2909      *        Must be equal to computeRedLevel for tree of this size.
2910      */
2911     @SuppressWarnings("unchecked")
buildFromSorted(int level, int lo, int hi, int redLevel, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal)2912     private final TreeMapEntry<K,V> buildFromSorted(int level, int lo, int hi,
2913                                              int redLevel,
2914                                              Iterator<?> it,
2915                                              java.io.ObjectInputStream str,
2916                                              V defaultVal)
2917         throws  java.io.IOException, ClassNotFoundException {
2918         /*
2919          * Strategy: The root is the middlemost element. To get to it, we
2920          * have to first recursively construct the entire left subtree,
2921          * so as to grab all of its elements. We can then proceed with right
2922          * subtree.
2923          *
2924          * The lo and hi arguments are the minimum and maximum
2925          * indices to pull out of the iterator or stream for current subtree.
2926          * They are not actually indexed, we just proceed sequentially,
2927          * ensuring that items are extracted in corresponding order.
2928          */
2929 
2930         if (hi < lo) return null;
2931 
2932         int mid = (lo + hi) >>> 1;
2933 
2934         TreeMapEntry<K,V> left  = null;
2935         if (lo < mid)
2936             left = buildFromSorted(level+1, lo, mid - 1, redLevel,
2937                                    it, str, defaultVal);
2938 
2939         // extract key and/or value from iterator or stream
2940         K key;
2941         V value;
2942         if (it != null) {
2943             if (defaultVal==null) {
2944                 Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next();
2945                 key = (K)entry.getKey();
2946                 value = (V)entry.getValue();
2947             } else {
2948                 key = (K)it.next();
2949                 value = defaultVal;
2950             }
2951         } else { // use stream
2952             key = (K) str.readObject();
2953             value = (defaultVal != null ? defaultVal : (V) str.readObject());
2954         }
2955 
2956         TreeMapEntry<K,V> middle =  new TreeMapEntry<>(key, value, null);
2957 
2958         // color nodes in non-full bottommost level red
2959         if (level == redLevel)
2960             middle.color = RED;
2961 
2962         if (left != null) {
2963             middle.left = left;
2964             left.parent = middle;
2965         }
2966 
2967         if (mid < hi) {
2968             TreeMapEntry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
2969                                                it, str, defaultVal);
2970             middle.right = right;
2971             right.parent = middle;
2972         }
2973 
2974         return middle;
2975     }
2976 
2977     /**
2978      * Finds the level down to which to assign all nodes BLACK.  This is the
2979      * last `full' level of the complete binary tree produced by buildTree.
2980      * The remaining nodes are colored RED. (This makes a `nice' set of
2981      * color assignments wrt future insertions.) This level number is
2982      * computed by finding the number of splits needed to reach the zeroeth
2983      * node.
2984      *
2985      * @param size the (non-negative) number of keys in the tree to be built
2986      */
computeRedLevel(int size)2987     private static int computeRedLevel(int size) {
2988         return 31 - Integer.numberOfLeadingZeros(size + 1);
2989     }
2990 
2991     /**
2992      * Currently, we support Spliterator-based versions only for the
2993      * full map, in either plain of descending form, otherwise relying
2994      * on defaults because size estimation for submaps would dominate
2995      * costs. The type tests needed to check these for key views are
2996      * not very nice but avoid disrupting existing class
2997      * structures. Callers must use plain default spliterators if this
2998      * returns null.
2999      */
keySpliteratorFor(NavigableMap<K,?> m)3000     static <K> Spliterator<K> keySpliteratorFor(NavigableMap<K,?> m) {
3001         if (m instanceof TreeMap) {
3002             @SuppressWarnings("unchecked") TreeMap<K,Object> t =
3003                 (TreeMap<K,Object>) m;
3004             return t.keySpliterator();
3005         }
3006         if (m instanceof DescendingSubMap) {
3007             @SuppressWarnings("unchecked") DescendingSubMap<K,?> dm =
3008                 (DescendingSubMap<K,?>) m;
3009             TreeMap<K,?> tm = dm.m;
3010             if (dm == tm.descendingMap) {
3011                 @SuppressWarnings("unchecked") TreeMap<K,Object> t =
3012                     (TreeMap<K,Object>) tm;
3013                 return t.descendingKeySpliterator();
3014             }
3015         }
3016         @SuppressWarnings("unchecked") NavigableSubMap<K,?> sm =
3017             (NavigableSubMap<K,?>) m;
3018         return sm.keySpliterator();
3019     }
3020 
keySpliterator()3021     final Spliterator<K> keySpliterator() {
3022         return new KeySpliterator<>(this, null, null, 0, -1, 0);
3023     }
3024 
descendingKeySpliterator()3025     final Spliterator<K> descendingKeySpliterator() {
3026         return new DescendingKeySpliterator<>(this, null, null, 0, -2, 0);
3027     }
3028 
3029     /**
3030      * Base class for spliterators.  Iteration starts at a given
3031      * origin and continues up to but not including a given fence (or
3032      * null for end).  At top-level, for ascending cases, the first
3033      * split uses the root as left-fence/right-origin. From there,
3034      * right-hand splits replace the current fence with its left
3035      * child, also serving as origin for the split-off spliterator.
3036      * Left-hands are symmetric. Descending versions place the origin
3037      * at the end and invert ascending split rules.  This base class
3038      * is non-committal about directionality, or whether the top-level
3039      * spliterator covers the whole tree. This means that the actual
3040      * split mechanics are located in subclasses. Some of the subclass
3041      * trySplit methods are identical (except for return types), but
3042      * not nicely factorable.
3043      *
3044      * Currently, subclass versions exist only for the full map
3045      * (including descending keys via its descendingMap).  Others are
3046      * possible but currently not worthwhile because submaps require
3047      * O(n) computations to determine size, which substantially limits
3048      * potential speed-ups of using custom Spliterators versus default
3049      * mechanics.
3050      *
3051      * To bootstrap initialization, external constructors use
3052      * negative size estimates: -1 for ascend, -2 for descend.
3053      */
3054     static class TreeMapSpliterator<K,V> {
3055         final TreeMap<K,V> tree;
3056         TreeMapEntry<K,V> current; // traverser; initially first node in range
3057         TreeMapEntry<K,V> fence;   // one past last, or null
3058         int side;                   // 0: top, -1: is a left split, +1: right
3059         int est;                    // size estimate (exact only for top-level)
3060         int expectedModCount;       // for CME checks
3061 
TreeMapSpliterator(TreeMap<K,V> tree, TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence, int side, int est, int expectedModCount)3062         TreeMapSpliterator(TreeMap<K,V> tree,
3063                            TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence,
3064                            int side, int est, int expectedModCount) {
3065             this.tree = tree;
3066             this.current = origin;
3067             this.fence = fence;
3068             this.side = side;
3069             this.est = est;
3070             this.expectedModCount = expectedModCount;
3071         }
3072 
getEstimate()3073         final int getEstimate() { // force initialization
3074             int s; TreeMap<K,V> t;
3075             if ((s = est) < 0) {
3076                 if ((t = tree) != null) {
3077                     current = (s == -1) ? t.getFirstEntry() : t.getLastEntry();
3078                     s = est = t.size;
3079                     expectedModCount = t.modCount;
3080                 }
3081                 else
3082                     s = est = 0;
3083             }
3084             return s;
3085         }
3086 
estimateSize()3087         public final long estimateSize() {
3088             return (long)getEstimate();
3089         }
3090     }
3091 
3092     static final class KeySpliterator<K,V>
3093         extends TreeMapSpliterator<K,V>
3094         implements Spliterator<K> {
KeySpliterator(TreeMap<K,V> tree, TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence, int side, int est, int expectedModCount)3095         KeySpliterator(TreeMap<K,V> tree,
3096                        TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence,
3097                        int side, int est, int expectedModCount) {
3098             super(tree, origin, fence, side, est, expectedModCount);
3099         }
3100 
trySplit()3101         public KeySpliterator<K,V> trySplit() {
3102             if (est < 0)
3103                 getEstimate(); // force initialization
3104             int d = side;
3105             TreeMapEntry<K,V> e = current, f = fence,
3106                 s = ((e == null || e == f) ? null :      // empty
3107                      (d == 0)              ? tree.root : // was top
3108                      (d >  0)              ? e.right :   // was right
3109                      (d <  0 && f != null) ? f.left :    // was left
3110                      null);
3111             if (s != null && s != e && s != f &&
3112                 tree.compare(e.key, s.key) < 0) {        // e not already past s
3113                 side = 1;
3114                 return new KeySpliterator<>
3115                     (tree, e, current = s, -1, est >>>= 1, expectedModCount);
3116             }
3117             return null;
3118         }
3119 
forEachRemaining(Consumer<? super K> action)3120         public void forEachRemaining(Consumer<? super K> action) {
3121             if (action == null)
3122                 throw new NullPointerException();
3123             if (est < 0)
3124                 getEstimate(); // force initialization
3125             TreeMapEntry<K,V> f = fence, e, p, pl;
3126             if ((e = current) != null && e != f) {
3127                 current = f; // exhaust
3128                 do {
3129                     action.accept(e.key);
3130                     if ((p = e.right) != null) {
3131                         while ((pl = p.left) != null)
3132                             p = pl;
3133                     }
3134                     else {
3135                         while ((p = e.parent) != null && e == p.right)
3136                             e = p;
3137                     }
3138                 } while ((e = p) != null && e != f);
3139                 if (tree.modCount != expectedModCount)
3140                     throw new ConcurrentModificationException();
3141             }
3142         }
3143 
tryAdvance(Consumer<? super K> action)3144         public boolean tryAdvance(Consumer<? super K> action) {
3145             TreeMapEntry<K,V> e;
3146             if (action == null)
3147                 throw new NullPointerException();
3148             if (est < 0)
3149                 getEstimate(); // force initialization
3150             if ((e = current) == null || e == fence)
3151                 return false;
3152             current = successor(e);
3153             action.accept(e.key);
3154             if (tree.modCount != expectedModCount)
3155                 throw new ConcurrentModificationException();
3156             return true;
3157         }
3158 
characteristics()3159         public int characteristics() {
3160             return (side == 0 ? Spliterator.SIZED : 0) |
3161                 Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
3162         }
3163 
getComparator()3164         public final Comparator<? super K>  getComparator() {
3165             return tree.comparator;
3166         }
3167 
3168     }
3169 
3170     static final class DescendingKeySpliterator<K,V>
3171         extends TreeMapSpliterator<K,V>
3172         implements Spliterator<K> {
DescendingKeySpliterator(TreeMap<K,V> tree, TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence, int side, int est, int expectedModCount)3173         DescendingKeySpliterator(TreeMap<K,V> tree,
3174                                  TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence,
3175                                  int side, int est, int expectedModCount) {
3176             super(tree, origin, fence, side, est, expectedModCount);
3177         }
3178 
trySplit()3179         public DescendingKeySpliterator<K,V> trySplit() {
3180             if (est < 0)
3181                 getEstimate(); // force initialization
3182             int d = side;
3183             TreeMapEntry<K,V> e = current, f = fence,
3184                     s = ((e == null || e == f) ? null :      // empty
3185                          (d == 0)              ? tree.root : // was top
3186                          (d <  0)              ? e.left :    // was left
3187                          (d >  0 && f != null) ? f.right :   // was right
3188                          null);
3189             if (s != null && s != e && s != f &&
3190                 tree.compare(e.key, s.key) > 0) {       // e not already past s
3191                 side = 1;
3192                 return new DescendingKeySpliterator<>
3193                         (tree, e, current = s, -1, est >>>= 1, expectedModCount);
3194             }
3195             return null;
3196         }
3197 
forEachRemaining(Consumer<? super K> action)3198         public void forEachRemaining(Consumer<? super K> action) {
3199             if (action == null)
3200                 throw new NullPointerException();
3201             if (est < 0)
3202                 getEstimate(); // force initialization
3203             TreeMapEntry<K,V> f = fence, e, p, pr;
3204             if ((e = current) != null && e != f) {
3205                 current = f; // exhaust
3206                 do {
3207                     action.accept(e.key);
3208                     if ((p = e.left) != null) {
3209                         while ((pr = p.right) != null)
3210                             p = pr;
3211                     }
3212                     else {
3213                         while ((p = e.parent) != null && e == p.left)
3214                             e = p;
3215                     }
3216                 } while ((e = p) != null && e != f);
3217                 if (tree.modCount != expectedModCount)
3218                     throw new ConcurrentModificationException();
3219             }
3220         }
3221 
tryAdvance(Consumer<? super K> action)3222         public boolean tryAdvance(Consumer<? super K> action) {
3223             TreeMapEntry<K,V> e;
3224             if (action == null)
3225                 throw new NullPointerException();
3226             if (est < 0)
3227                 getEstimate(); // force initialization
3228             if ((e = current) == null || e == fence)
3229                 return false;
3230             current = predecessor(e);
3231             action.accept(e.key);
3232             if (tree.modCount != expectedModCount)
3233                 throw new ConcurrentModificationException();
3234             return true;
3235         }
3236 
characteristics()3237         public int characteristics() {
3238             return (side == 0 ? Spliterator.SIZED : 0) |
3239                 Spliterator.DISTINCT | Spliterator.ORDERED;
3240         }
3241     }
3242 
3243     static final class ValueSpliterator<K,V>
3244             extends TreeMapSpliterator<K,V>
3245             implements Spliterator<V> {
ValueSpliterator(TreeMap<K,V> tree, TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence, int side, int est, int expectedModCount)3246         ValueSpliterator(TreeMap<K,V> tree,
3247                          TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence,
3248                          int side, int est, int expectedModCount) {
3249             super(tree, origin, fence, side, est, expectedModCount);
3250         }
3251 
trySplit()3252         public ValueSpliterator<K,V> trySplit() {
3253             if (est < 0)
3254                 getEstimate(); // force initialization
3255             int d = side;
3256             TreeMapEntry<K,V> e = current, f = fence,
3257                     s = ((e == null || e == f) ? null :      // empty
3258                          (d == 0)              ? tree.root : // was top
3259                          (d >  0)              ? e.right :   // was right
3260                          (d <  0 && f != null) ? f.left :    // was left
3261                          null);
3262             if (s != null && s != e && s != f &&
3263                 tree.compare(e.key, s.key) < 0) {        // e not already past s
3264                 side = 1;
3265                 return new ValueSpliterator<>
3266                         (tree, e, current = s, -1, est >>>= 1, expectedModCount);
3267             }
3268             return null;
3269         }
3270 
forEachRemaining(Consumer<? super V> action)3271         public void forEachRemaining(Consumer<? super V> action) {
3272             if (action == null)
3273                 throw new NullPointerException();
3274             if (est < 0)
3275                 getEstimate(); // force initialization
3276             TreeMapEntry<K,V> f = fence, e, p, pl;
3277             if ((e = current) != null && e != f) {
3278                 current = f; // exhaust
3279                 do {
3280                     action.accept(e.value);
3281                     if ((p = e.right) != null) {
3282                         while ((pl = p.left) != null)
3283                             p = pl;
3284                     }
3285                     else {
3286                         while ((p = e.parent) != null && e == p.right)
3287                             e = p;
3288                     }
3289                 } while ((e = p) != null && e != f);
3290                 if (tree.modCount != expectedModCount)
3291                     throw new ConcurrentModificationException();
3292             }
3293         }
3294 
tryAdvance(Consumer<? super V> action)3295         public boolean tryAdvance(Consumer<? super V> action) {
3296             TreeMapEntry<K,V> e;
3297             if (action == null)
3298                 throw new NullPointerException();
3299             if (est < 0)
3300                 getEstimate(); // force initialization
3301             if ((e = current) == null || e == fence)
3302                 return false;
3303             current = successor(e);
3304             action.accept(e.value);
3305             if (tree.modCount != expectedModCount)
3306                 throw new ConcurrentModificationException();
3307             return true;
3308         }
3309 
characteristics()3310         public int characteristics() {
3311             return (side == 0 ? Spliterator.SIZED : 0) | Spliterator.ORDERED;
3312         }
3313     }
3314 
3315     static final class EntrySpliterator<K,V>
3316         extends TreeMapSpliterator<K,V>
3317         implements Spliterator<Map.Entry<K,V>> {
EntrySpliterator(TreeMap<K,V> tree, TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence, int side, int est, int expectedModCount)3318         EntrySpliterator(TreeMap<K,V> tree,
3319                          TreeMapEntry<K,V> origin, TreeMapEntry<K,V> fence,
3320                          int side, int est, int expectedModCount) {
3321             super(tree, origin, fence, side, est, expectedModCount);
3322         }
3323 
trySplit()3324         public EntrySpliterator<K,V> trySplit() {
3325             if (est < 0)
3326                 getEstimate(); // force initialization
3327             int d = side;
3328             TreeMapEntry<K,V> e = current, f = fence,
3329                     s = ((e == null || e == f) ? null :      // empty
3330                          (d == 0)              ? tree.root : // was top
3331                          (d >  0)              ? e.right :   // was right
3332                          (d <  0 && f != null) ? f.left :    // was left
3333                          null);
3334             if (s != null && s != e && s != f &&
3335                 tree.compare(e.key, s.key) < 0) {        // e not already past s
3336                 side = 1;
3337                 return new EntrySpliterator<>
3338                         (tree, e, current = s, -1, est >>>= 1, expectedModCount);
3339             }
3340             return null;
3341         }
3342 
forEachRemaining(Consumer<? super Map.Entry<K, V>> action)3343         public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
3344             if (action == null)
3345                 throw new NullPointerException();
3346             if (est < 0)
3347                 getEstimate(); // force initialization
3348             TreeMapEntry<K,V> f = fence, e, p, pl;
3349             if ((e = current) != null && e != f) {
3350                 current = f; // exhaust
3351                 do {
3352                     action.accept(e);
3353                     if ((p = e.right) != null) {
3354                         while ((pl = p.left) != null)
3355                             p = pl;
3356                     }
3357                     else {
3358                         while ((p = e.parent) != null && e == p.right)
3359                             e = p;
3360                     }
3361                 } while ((e = p) != null && e != f);
3362                 if (tree.modCount != expectedModCount)
3363                     throw new ConcurrentModificationException();
3364             }
3365         }
3366 
tryAdvance(Consumer<? super Map.Entry<K,V>> action)3367         public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
3368             TreeMapEntry<K,V> e;
3369             if (action == null)
3370                 throw new NullPointerException();
3371             if (est < 0)
3372                 getEstimate(); // force initialization
3373             if ((e = current) == null || e == fence)
3374                 return false;
3375             current = successor(e);
3376             action.accept(e);
3377             if (tree.modCount != expectedModCount)
3378                 throw new ConcurrentModificationException();
3379             return true;
3380         }
3381 
characteristics()3382         public int characteristics() {
3383             return (side == 0 ? Spliterator.SIZED : 0) |
3384                     Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
3385         }
3386 
3387         @Override
getComparator()3388         public Comparator<Map.Entry<K, V>> getComparator() {
3389             // Adapt or create a key-based comparator
3390             if (tree.comparator != null) {
3391                 return Map.Entry.comparingByKey(tree.comparator);
3392             }
3393             else {
3394                 return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> {
3395                     @SuppressWarnings("unchecked")
3396                     Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
3397                     return k1.compareTo(e2.getKey());
3398                 };
3399             }
3400         }
3401     }
3402 }
3403