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