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