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