001/*
002 * Copyright (C) 2002-2015 Sebastiano Vigna
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package squidpony.squidmath;
017
018import squidpony.annotation.GwtIncompatible;
019
020import java.io.Serializable;
021import java.util.*;
022
023/**
024 * A generic insertion-ordered hash map with with a fast implementation, originally from fastutil as
025 * Object2ObjectLinkedOpenHashMap but modified to support constant-time indexed access of keys, values, and entries,
026 * reordering, and optional hash strategies for unusual keys, such as arrays or usually-dense numeric values.
027 * <br>
028 * Instances of this class use a hash table to represent a map. The table is filled up to a specified <em>load factor</em>, and then doubled in size to accommodate new entries. If the table is
029 * emptied below <em>one fourth</em> of the load factor, it is halved in size. However, halving is not performed when deleting entries from an iterator, as it would interfere with the iteration
030 * process.
031 * <br>
032 * Note that {@link #clear()} does not modify the hash table size. Rather, a family of {@linkplain #trim() trimming methods} lets you control the size of the table; this is particularly useful if
033 * you reuse instances of this class.
034 * <br>
035 * Iterators generated by this map will enumerate pairs in the same order in which they have been added to the map (addition of pairs whose key is already present in the set does not change the
036 * iteration order). Note that this order has nothing in common with the natural order of the keys. The order is kept by means of a int-specialized list, {@link IntVLA}, and is modifiable with this
037 * class' {@link #reorder(int...)} and {@link #shuffle(IRNG)} methods, among other tools. It may be preferable to avoid instantiating an Iterator object and instead
038 * use a normal int-based for loop with {@link #getAt(int)} called in each iteration. Though this doesn't allow easy deletion of items during iteration, it may be the
039 * fastest way to iterate through an OrderedMap.
040 * <br>
041 * This class implements the interface of a sorted map, so to allow easy access of the iteration order: for instance, you can get the first key in iteration order with {@code firstKey()} without
042 * having to create an iterator; however, this class partially violates the {@link SortedMap} contract because all submap methods throw an exception and {@link #comparator()} returns always
043 * <code>null</code>.
044 * <br>
045 * Additional methods, such as <code>getAndMoveToFirst()</code>, make it easy to use instances of this class as a cache (e.g., with LRU policy).
046 * <br>
047 * This class allows approximately constant-time lookup of keys or values by their index in the ordering, which can
048 * allow some novel usage of the data structure. {@link OrderedSet} can be used like a list of unique elements, keeping
049 * order like a list does but also allowing rapid checks for whether an item exists in the OrderedSet, and OrderedMap
050 * can be used like that but with values associated as well (where OrderedSet uses contains(), OrderedMap uses
051 * containsKey()). You can also set the key and value at a position with {@link #putAt(Object, Object, int)}, or alter
052 * the key while keeping its value and index the same with {@link #alter(Object, Object)}. Reordering works here too,
053 * both with completely random orders from {@link #shuffle(IRNG)} or with a previously-generated ordering from
054 * {@link #reorder(int...)} (you can produce such an ordering for a given size and reuse it across multiple Ordered data
055 * structures with {@link IRNG#randomOrdering(int)}). Note that putAt() and {@link #removeAt(int)} do not run in constant
056 * time, and depending on the point of insertion/removal, they are likely to run in linear time (but also note that most
057 * insertion-ordered Maps and Sets don't allow insertion or removal at anywhere but the beginning or end of the order).
058 * <br>
059 * You can pass a {@link CrossHash.IHasher} instance such as {@link CrossHash#generalHasher} as an extra parameter to
060 * most of this class' constructors, which allows the OrderedMap to use arrays (usually primitive arrays) as keys. If
061 * you expect only one type of array, you can use an instance like {@link CrossHash#intHasher} to hash int arrays, or
062 * the aforementioned generalHasher to hash most kinds of arrays (it can't handle most multi-dimensional arrays well).
063 * If you aren't using arrays as keys, you don't need to give an IHasher to the constructor and can ignore this feature
064 * most of the time. However, the default IHasher this uses if none is specified performs a small but significant
065 * "mixing" step to make the default generated hashCode() implementation many classes use into a higher-quality
066 * random-like value. This isn't always optimal; if you plan to insert 1000 sequential Integer keys with some small
067 * amount of random Integers after them, then the mixing actually increases the likelihood of a collision and takes time
068 * to calculate. You could use a very simple IHasher in that case, relying on the fact that only Integers will be added:
069 * <pre>
070 * new CrossHash.IHasher() {
071 *     public int hash(Object data) { return (int)data; }
072 *     public boolean areEqual(Object left, Object right) { return Objects.equals(left, right); }
073 * };
074 * </pre>
075 * This is just one example of a case where a custom IHasher can be useful for performance reasons; there are also cases
076 * where an IHasher is needed to enforce hashing by identity or by value, which affect program logic. Note that the
077 * given IHasher is likely to be sub-optimal for many situations with Integer keys, and you may want to try a few
078 * different approaches if you know OrderedMap is a bottleneck in your application. If the IHasher is a performance
079 * problem, it will be at its worst if the OrderedMap needs to resize, and thus rehash, many times; this won't happen if
080 * the capacity is set correctly when the OrderedMap is created (with the capacity equal to or greater than the maximum
081 * number of entries that will be added).
082 * <br>
083 * Thank you, Sebastiano Vigna, for making FastUtil available to the public with such high quality.
084 * <br>
085 * See https://github.com/vigna/fastutil for the original library.
086 * @author Sebastiano Vigna (responsible for all the hard parts)
087 * @author Tommy Ettinger (mostly responsible for squashing several layers of parent classes into one monster class)
088 */
089public class OrderedMap<K, V> implements SortedMap<K, V>, java.io.Serializable, Cloneable {
090    private static final long serialVersionUID = 0L;
091    /**
092     * The array of keys.
093     */
094    protected K[] key;
095    /**
096     * The array of values.
097     */
098    protected V[] value;
099    /**
100     * The mask for wrapping a position counter.
101     */
102    protected int mask;
103    /**
104     * Whether this set contains the key zero.
105     */
106    protected boolean containsNullKey;
107    /**
108     * An IntVLA (variable-length int sequence) that stores the positions in the key array of specific keys, with the
109     * positions in insertion order. The order can be changed with {@link #reorder(int...)} and other methods.
110     */
111    protected IntVLA order;
112    /**
113     * The current table size.
114     */
115    protected int n;
116    /**
117     * Threshold after which we rehash. It must be the table size times {@link #f}.
118     */
119    protected int maxFill;
120    /**
121     * Number of entries in the set (including the key zero, if present).
122     */
123    protected int size;
124    /**
125     * The acceptable load factor.
126     */
127    public final float f;
128    /**
129     * Cached set of entries.
130     */
131    protected volatile MapEntrySet entries;
132    /**
133     * Cached set of keys.
134     */
135    protected volatile KeySet keys;
136    /**
137     * Cached collection of values.
138     */
139    protected volatile Collection<V> values;
140    /**
141     * Default return value.
142     */
143    protected V defRetValue;
144
145    /**
146     * The initial default size of a hash table.
147     */
148    public static final int DEFAULT_INITIAL_SIZE = 16;
149    /**
150     * The default load factor of a hash table.
151     */
152    public static final float DEFAULT_LOAD_FACTOR = .25f; // .1875f; // .75f;
153    /**
154     * The load factor for a (usually small) table that is meant to be particularly fast.
155     */
156    public static final float FAST_LOAD_FACTOR = .5f;
157    /**
158     * The load factor for a (usually very small) table that is meant to be extremely fast.
159     */
160    public static final float VERY_FAST_LOAD_FACTOR = .25f;
161
162    protected final CrossHash.IHasher hasher;
163
164    public void defaultReturnValue(final V rv) {
165        defRetValue = rv;
166    }
167
168    public V defaultReturnValue() {
169        return defRetValue;
170    }
171
172    /**
173     * Creates a new OrderedMap.
174     * <p>
175     * <p>The actual table size will be the least power of two greater than <code>expected</code>/<code>f</code>.
176     *
177     * @param expected the expected number of elements in the hash set.
178     * @param f        the load factor.
179     */
180
181    @SuppressWarnings("unchecked")
182    public OrderedMap(final int expected, final float f) {
183        if (f <= 0 || f > 1)
184            throw new IllegalArgumentException("Load factor must be greater than 0 and smaller than or equal to 1");
185        if (expected < 0) throw new IllegalArgumentException("The expected number of elements must be nonnegative");
186        this.f = f;
187        n = arraySize(expected, f);
188        mask = n - 1;
189        maxFill = maxFill(n, f);
190        key = (K[]) new Object[n + 1];
191        value = (V[]) new Object[n + 1];
192        //link = new long[n + 1];
193        order = new IntVLA(expected);
194        hasher = CrossHash.mildHasher;
195    }
196
197    /**
198     * Creates a new OrderedMap with 0.75f as load factor.
199     *
200     * @param expected the expected number of elements in the OrderedMap.
201     */
202    public OrderedMap(final int expected) {
203        this(expected, DEFAULT_LOAD_FACTOR);
204    }
205
206    /**
207     * Creates a new OrderedMap with initial expected 16 entries and 0.75f as load factor.
208     */
209    public OrderedMap() {
210        this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR);
211    }
212
213    /**
214     * Creates a new OrderedMap copying a given one.
215     *
216     * @param m a {@link Map} to be copied into the new OrderedMap.
217     * @param f the load factor.
218     */
219    public OrderedMap(final Map<? extends K, ? extends V> m, final float f) {
220        this(m.size(), f, (m instanceof OrderedMap) ? ((OrderedMap) m).hasher : CrossHash.mildHasher);
221        putAll(m);
222    }
223
224    /**
225     * Creates a new OrderedMap with 0.75f as load factor copying a given one.
226     *
227     * @param m a {@link Map} to be copied into the new OrderedMap.
228     */
229    public OrderedMap(final Map<? extends K, ? extends V> m) {
230        this(m, (m instanceof OrderedMap) ? ((OrderedMap) m).f : DEFAULT_LOAD_FACTOR, (m instanceof OrderedMap) ? ((OrderedMap) m).hasher : CrossHash.mildHasher);
231    }
232
233    /**
234     * Creates a new OrderedMap using the elements of two parallel arrays.
235     *
236     * @param keyArray the array of keys of the new OrderedMap.
237     * @param valueArray the array of corresponding values in the new OrderedMap.
238     * @param f the load factor.
239     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
240     */
241    public OrderedMap(final K[] keyArray, final V[] valueArray, final float f) {
242        this(keyArray.length, f);
243        if (keyArray.length != valueArray.length)
244            throw new IllegalArgumentException("The key array and the value array have different lengths (" + keyArray.length + " and " + valueArray.length + ")");
245        for (int i = 0; i < keyArray.length; i++)
246            put(keyArray[i], valueArray[i]);
247    }
248    /**
249     * Creates a new OrderedMap using the elements of two parallel arrays.
250     *
251     * @param keyColl the collection of keys of the new OrderedMap.
252     * @param valueColl the collection of corresponding values in the new OrderedMap.
253     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
254     */
255    public OrderedMap(final Collection<K> keyColl, final Collection<V> valueColl) {
256        this(keyColl, valueColl, DEFAULT_LOAD_FACTOR);
257    }
258    /**
259     * Creates a new OrderedMap using the elements of two parallel arrays.
260     *
261     * @param keyColl the collection of keys of the new OrderedMap.
262     * @param valueColl the collection of corresponding values in the new OrderedMap.
263     * @param f the load factor.
264     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
265     */
266    public OrderedMap(final Collection<K> keyColl, final Collection<V> valueColl, final float f) {
267        this(keyColl.size(), f);
268        if (keyColl.size() != valueColl.size())
269            throw new IllegalArgumentException("The key array and the value array have different lengths (" + keyColl.size() + " and " + valueColl.size() + ")");
270        Iterator<K> ki = keyColl.iterator();
271        Iterator<V> vi = valueColl.iterator();
272        while (ki.hasNext() && vi.hasNext())
273        {
274            put(ki.next(), vi.next());
275        }
276    }
277
278    /**
279     * Creates a new OrderedMap with 0.75f as load factor using the elements of two parallel arrays.
280     *
281     * @param keyArray the array of keys of the new OrderedMap.
282     * @param valueArray the array of corresponding values in the new OrderedMap.
283     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
284     */
285    public OrderedMap(final K[] keyArray, final V[] valueArray) {
286        this(keyArray, valueArray, DEFAULT_LOAD_FACTOR);
287    }
288
289    /**
290     * Creates a new OrderedMap.
291     * <p>
292     * <p>The actual table size will be the least power of two greater than <code>expected</code>/<code>f</code>.
293     *
294     * @param expected the expected number of elements in the hash set.
295     * @param f        the load factor.
296     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
297     */
298
299    @SuppressWarnings("unchecked")
300    public OrderedMap(final int expected, final float f, CrossHash.IHasher hasher) {
301        if (f <= 0 || f > 1)
302            throw new IllegalArgumentException("Load factor must be greater than 0 and smaller than or equal to 1");
303        if (expected < 0) throw new IllegalArgumentException("The expected number of elements must be nonnegative");
304        this.f = f;
305        n = arraySize(expected, f);
306        mask = n - 1;
307        maxFill = maxFill(n, f);
308        key = (K[]) new Object[n + 1];
309        value = (V[]) new Object[n + 1];
310        //link = new long[n + 1];
311        order = new IntVLA(expected);
312        this.hasher = (hasher == null) ? CrossHash.mildHasher : hasher;
313    }
314    /**
315     * Creates a new OrderedMap with 0.75f as load factor.
316     *
317     * @param expected the expected number of elements in the OrderedMap.
318     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
319     */
320    public OrderedMap(final int expected, CrossHash.IHasher hasher) {
321        this(expected, DEFAULT_LOAD_FACTOR, hasher);
322    }
323
324    /**
325     * Creates a new OrderedMap with initial expected 16 entries and 0.75f as load factor.
326     */
327    public OrderedMap(CrossHash.IHasher hasher) {
328        this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR, hasher);
329    }
330
331    /**
332     * Creates a new OrderedMap copying a given one.
333     *
334     * @param m a {@link Map} to be copied into the new OrderedMap.
335     * @param f the load factor.
336     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
337     */
338    public OrderedMap(final Map<? extends K, ? extends V> m, final float f, CrossHash.IHasher hasher) {
339        this(m.size(), f, hasher);
340        putAll(m);
341    }
342
343    /**
344     * Creates a new OrderedMap with 0.75f as load factor copying a given one.
345     * @param m a {@link Map} to be copied into the new OrderedMap.
346     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
347     */
348    public OrderedMap(final Map<? extends K, ? extends V> m, CrossHash.IHasher hasher) {
349        this(m, DEFAULT_LOAD_FACTOR, hasher);
350    }
351
352    /**
353     * Creates a new OrderedMap using the elements of two parallel arrays.
354     *
355     * @param keyArray the array of keys of the new OrderedMap.
356     * @param valueArray the array of corresponding values in the new OrderedMap.
357     * @param f the load factor.
358     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
359     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
360     */
361    public OrderedMap(final K[] keyArray, final V[] valueArray, final float f, CrossHash.IHasher hasher) {
362        this(keyArray.length, f, hasher);
363        if (keyArray.length != valueArray.length)
364            throw new IllegalArgumentException("The key array and the value array have different lengths (" + keyArray.length + " and " + valueArray.length + ")");
365        for (int i = 0; i < keyArray.length; i++)
366            put(keyArray[i], valueArray[i]);
367    }
368    /**
369     * Creates a new OrderedMap with 0.75f as load factor using the elements of two parallel arrays.
370     *
371     * @param keyArray the array of keys of the new OrderedMap.
372     * @param valueArray the array of corresponding values in the new OrderedMap.
373     * @param hasher used to hash items; typically only needed when K is an array, where CrossHash has implementations
374     * @throws IllegalArgumentException if <code>k</code> and <code>v</code> have different lengths.
375     */
376    public OrderedMap(final K[] keyArray, final V[] valueArray, CrossHash.IHasher hasher) {
377        this(keyArray, valueArray, DEFAULT_LOAD_FACTOR, hasher);
378    }
379
380    private int realSize() {
381        return containsNullKey ? size - 1 : size;
382    }
383    
384    public void ensureCapacity(final int capacity) {
385        final int needed = arraySize(capacity, f);
386        if (needed > n)
387            rehash(needed);
388    }
389    private void tryCapacity(final long capacity) {
390        final int needed = (int) Math.min(
391                1 << 30,
392                Math.max(2, HashCommon.nextPowerOfTwo((long) Math.ceil(capacity
393                        / f))));
394        if (needed > n)
395            rehash(needed);
396    }
397    protected V removeEntry(final int pos) {
398        final V oldValue = value[pos];
399        value[pos] = null;
400        size--;
401        fixOrder(pos);
402        shiftKeys(pos);
403        if (size < maxFill / 4 && n > DEFAULT_INITIAL_SIZE)
404            rehash(n / 2);
405        return oldValue;
406    }
407    protected V removeNullEntry() {
408        containsNullKey = false;
409        key[n] = null;
410        final V oldValue = value[n];
411        value[n] = null;
412        size--;
413        fixOrder(n);
414        if (size < maxFill / 4 && n > DEFAULT_INITIAL_SIZE)
415            rehash(n / 2);
416        return oldValue;
417    }
418
419    /**
420     * Puts the first key in keyArray with the first value in valueArray, then the second in each and so on.
421     * The entries are all appended to the end of the iteration order, unless a key was already present. Then,
422     * its value is changed at the existing position in the iteration order.
423     * If the lengths of the two arrays are not equal, this puts a number of entries equal to the lesser length.
424     * If either array is null, this returns without performing any changes.
425     * @param keyArray an array of K keys that should usually have the same length as valueArray
426     * @param valueArray an array of V values that should usually have the same length as keyArray
427     */
428    public void putAll(final K[] keyArray, final V[] valueArray)
429    {
430        if(keyArray == null || valueArray == null)
431            return;
432        for (int i = 0; i < keyArray.length && i < valueArray.length; i++)
433            put(keyArray[i], valueArray[i]);
434
435    }
436
437    /**
438     * Puts all key-value pairs in the Map m into this OrderedMap.
439     * The entries are all appended to the end of the iteration order, unless a key was already present. Then,
440     * its value is changed at the existing position in the iteration order. This can take any kind of Map,
441     * including unordered HashMap objects; if the Map does not have stable ordering, the order in which entries
442     * will be appended is not stable either. For this reason, OrderedMap, LinkedHashMap, and TreeMap (or other
443     * SortedMap implementations) will work best when order matters.
444     * @param m a Map that should have the same or compatible K key and V value types; OrderedMap and TreeMap work best
445     */
446    public void putAll(Map<? extends K, ? extends V> m) {
447        if (f <= .5)
448            ensureCapacity(m.size()); // The resulting map will be sized for
449            // m.size() elements
450        else
451            tryCapacity(size() + m.size()); // The resulting map will be
452        int n = m.size();
453        final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m
454                .entrySet().iterator();
455        if (m instanceof OrderedMap) {
456            Entry<? extends K, ? extends V> e;
457            while (n-- != 0) {
458                e = i.next();
459                put(e.getKey(), e.getValue());
460            }
461        } else {
462            Map.Entry<? extends K, ? extends V> e;
463            while (n-- != 0) {
464                e = i.next();
465                put(e.getKey(), e.getValue());
466            }
467        }
468    }
469    private int insert(final K k, final V v) {
470        int pos;
471        if (k == null) {
472            if (containsNullKey)
473                return n;
474            containsNullKey = true;
475            pos = n;
476        } else {
477            K curr;
478            final K[] key = this.key;
479            // The starting point.
480            if ((curr = key[pos = (hasher.hash(k)) & mask]) != null) {
481                if (hasher.areEqual(curr, k))
482                    return pos;
483                while ((curr = key[pos = (pos + 1) & mask]) != null)
484                    if (hasher.areEqual(curr, k))
485                        return pos;
486            }
487        }
488        key[pos] = k;
489        value[pos] = v;
490        order.add(pos);
491        if (size++ >= maxFill)
492            rehash(arraySize(size + 1, f));
493        return -1;
494    }
495    private int insertAt(final K k, final V v, final int idx) {
496        int pos;
497        if (k == null) {
498            if (containsNullKey)
499            {
500                fixOrder(n);
501                order.insert(idx, n);
502                return n;
503            }
504            containsNullKey = true;
505            pos = n;
506        } else {
507            K curr;
508            final K[] key = this.key;
509            // The starting point.
510            if ((curr = key[pos = (hasher.hash(k)) & mask]) != null) {
511                if (hasher.areEqual(curr, k))
512                {
513                    fixOrder(pos);
514                    order.insert(idx, pos);
515                    return pos;
516                }
517                while ((curr = key[pos = (pos + 1) & mask]) != null)
518                    if (hasher.areEqual(curr, k))
519                    {
520                        fixOrder(pos);
521                        order.insert(idx, pos);
522                        return pos;
523                    }
524            }
525        }
526        key[pos] = k;
527        value[pos] = v;
528        order.insert(idx, pos);
529        if (size++ >= maxFill)
530            rehash(arraySize(size + 1, f));
531        return -1;
532    }
533    public V put(final K k, final V v) {
534        final int pos = insert(k, v);
535        if (pos < 0)
536            return defRetValue;
537        final V oldValue = value[pos];
538        value[pos] = v;
539        return oldValue;
540    }
541    public V putAt(final K k, final V v, final int idx) {
542        final int pos = insertAt(k, v, idx);
543        if (pos < 0)
544            return defRetValue;
545        final V oldValue = value[pos];
546        value[pos] = v;
547        return oldValue;
548    }
549    /**
550     * Shifts left entries with the specified hash code, starting at the
551     * specified position, and empties the resulting free entry.
552     *
553     * @param pos
554     *            a starting position.
555     */
556    protected final void shiftKeys(int pos) {
557        // Shift entries with the same hash.
558        int last, slot;
559        K curr;
560        final K[] key = this.key;
561        for (;;) {
562            pos = ((last = pos) + 1) & mask;
563            for (;;) {
564                if ((curr = key[pos]) == null) {
565                    key[last] = null;
566                    value[last] = null;
567                    return;
568                }
569                slot = (hasher.hash(curr))
570                        & mask;
571                if (last <= pos ? last >= slot || slot > pos : last >= slot
572                        && slot > pos)
573                    break;
574                pos = (pos + 1) & mask;
575            }
576            key[last] = curr;
577            value[last] = value[pos];
578            fixOrder(pos, last);
579        }
580    }
581    public V remove(final Object k) {
582        if (k == null) {
583            if (containsNullKey)
584                return removeNullEntry();
585            return defRetValue;
586        }
587        K curr;
588        final K[] key = this.key;
589        int pos;
590        // The starting point.
591        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
592            return defRetValue;
593        if (hasher.areEqual(k, curr))
594            return removeEntry(pos);
595        while (true) {
596            if ((curr = key[pos = (pos + 1) & mask]) == null)
597                return defRetValue;
598            if (hasher.areEqual(k, curr))
599                return removeEntry(pos);
600        }
601    }
602    private V setValue(final int pos, final V v) {
603        final V oldValue = value[pos];
604        value[pos] = v;
605        return oldValue;
606    }
607    /**
608     * Removes the mapping associated with the first key in iteration order.
609     *
610     * @return the value previously associated with the first key in iteration
611     *         order.
612     * @throws NoSuchElementException
613     *             is this map is empty.
614     */
615    public V removeFirst() {
616        if (size == 0)
617            throw new NoSuchElementException();
618        final int pos = order.removeIndex(0);
619
620        size--;
621        final V v = value[pos];
622        if (pos == n) {
623            containsNullKey = false;
624            key[n] = null;
625            value[n] = null;
626        } else
627            shiftKeys(pos);
628        if (size < maxFill / 4 && n > DEFAULT_INITIAL_SIZE)
629            rehash(n / 2);
630        return v;
631    }
632    /**
633     * Removes the mapping associated with the last key in iteration order.
634     *
635     * @return the value previously associated with the last key in iteration
636     *         order.
637     * @throws NoSuchElementException
638     *             is this map is empty.
639     */
640    public V removeLast() {
641        if (size == 0)
642            throw new NoSuchElementException();
643        final int pos = order.items[order.size-1];
644        order.pop();
645        size--;
646        final V v = value[pos];
647        if (pos == n) {
648            containsNullKey = false;
649            key[n] = null;
650            value[n] = null;
651        } else
652            shiftKeys(pos);
653        if (size < maxFill / 4 && n > DEFAULT_INITIAL_SIZE)
654            rehash(n / 2);
655        return v;
656    }
657    private void moveIndexToFirst(final int i) {
658        if(size <= 1 || order.items[0] == i)
659            return;
660        order.moveToFirst(i);
661    }
662    private void moveIndexToLast(final int i) {
663        if(size <= 1 || order.items[order.size-1] == i)
664            return;
665        order.moveToLast(i);
666    }
667    /**
668     * Returns the value to which the given key is mapped; if the key is
669     * present, it is moved to the first position of the iteration order.
670     *
671     * @param k
672     *            the key.
673     * @return the corresponding value, or the
674     *         {@linkplain #defaultReturnValue() default return value} if no
675     *         value was present for the given key.
676     */
677    public V getAndMoveToFirst(final K k) {
678        if (k == null) {
679            if (containsNullKey) {
680                moveIndexToFirst(n);
681                return value[n];
682            }
683            return defRetValue;
684        }
685        K curr;
686        final K[] key = this.key;
687        int pos;
688        // The starting point.
689        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
690            return defRetValue;
691        if (hasher.areEqual(k, curr)) {
692            moveIndexToFirst(pos);
693            return value[pos];
694        }
695        // There's always an unused entry.
696        while (true) {
697            if ((curr = key[pos = (pos + 1) & mask]) == null)
698                return defRetValue;
699            if (hasher.areEqual(k, curr)) {
700                moveIndexToFirst(pos);
701                return value[pos];
702            }
703        }
704    }
705    /**
706     * Returns the value to which the given key is mapped; if the key is
707     * present, it is moved to the last position of the iteration order.
708     *
709     * @param k the key.
710     * @return the corresponding value, or the
711     *         {@linkplain #defaultReturnValue() default return value} if no
712     *         value was present for the given key.
713     */
714    public V getAndMoveToLast(final K k) {
715        if (k == null) {
716            if (containsNullKey) {
717                moveIndexToLast(n);
718                return value[n];
719            }
720            return defRetValue;
721        }
722        K curr;
723        final K[] key = this.key;
724        int pos;
725        // The starting point.
726        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
727            return defRetValue;
728        if (hasher.areEqual(k, curr)) {
729            moveIndexToLast(pos);
730            return value[pos];
731        }
732        // There's always an unused entry.
733        while (true) {
734            if ((curr = key[pos = (pos + 1) & mask]) == null)
735                return defRetValue;
736            if (hasher.areEqual(k, curr)) {
737                moveIndexToLast(pos);
738                return value[pos];
739            }
740        }
741    }
742    /**
743     * Adds a pair to the map; if the key is already present, it is moved to the
744     * first position of the iteration order.
745     *
746     * @param k
747     *            the key.
748     * @param v
749     *            the value.
750     * @return the old value, or the {@linkplain #defaultReturnValue() default
751     *         return value} if no value was present for the given key.
752     */
753    public V putAndMoveToFirst(final K k, final V v) {
754        int pos;
755        if (k == null) {
756            if (containsNullKey) {
757                moveIndexToFirst(n);
758                return setValue(n, v);
759            }
760            containsNullKey = true;
761            pos = n;
762        } else {
763            K curr;
764            final K[] key = this.key;
765            // The starting point.
766            if (!((curr = key[pos = (hasher.hash(k)) & mask]) == null)) {
767                if (hasher.areEqual(curr, k)) {
768                    moveIndexToFirst(pos);
769                    return setValue(pos, v);
770                }
771                while (!((curr = key[pos = (pos + 1) & mask]) == null))
772                    if (hasher.areEqual(curr, k)) {
773                        moveIndexToFirst(pos);
774                        return setValue(pos, v);
775                    }
776            }
777        }
778        key[pos] = k;
779        value[pos] = v;
780        order.insert(0, pos);
781        if (size++ >= maxFill)
782            rehash(arraySize(size, f));
783        return defRetValue;
784    }
785    /**
786     * Adds a pair to the map; if the key is already present, it is moved to the
787     * last position of the iteration order.
788     *
789     * @param k
790     *            the key.
791     * @param v
792     *            the value.
793     * @return the old value, or the {@linkplain #defaultReturnValue() default
794     *         return value} if no value was present for the given key.
795     */
796    public V putAndMoveToLast(final K k, final V v) {
797        int pos;
798        if (k == null) {
799            if (containsNullKey) {
800                moveIndexToLast(n);
801                return setValue(n, v);
802            }
803            containsNullKey = true;
804            pos = n;
805        } else {
806            K curr;
807            final K[] key = this.key;
808            // The starting point.
809            if (!((curr = key[pos = (hasher.hash(k)) & mask]) == null)) {
810                if (hasher.areEqual(curr, k)) {
811                    moveIndexToLast(pos);
812                    return setValue(pos, v);
813                }
814                while (!((curr = key[pos = (pos + 1) & mask]) == null))
815                    if (hasher.areEqual(curr, k)) {
816                        moveIndexToLast(pos);
817                        return setValue(pos, v);
818                    }
819            }
820        }
821        key[pos] = k;
822        value[pos] = v;
823        if(order.peek() != pos)
824            order.add(pos);
825        if (size++ >= maxFill)
826            rehash(arraySize(size, f));
827        return defRetValue;
828    }
829    public V get(final Object k) {
830        if (k == null)
831            return containsNullKey ? value[n] : defRetValue;
832        K curr;
833        final K[] key = this.key;
834        int pos;
835        // The starting point.
836        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
837            return defRetValue;
838        if (hasher.areEqual(k, curr))
839            return value[pos];
840        // There's always an unused entry.
841        while (true) {
842            if ((curr = key[pos = (pos + 1) & mask]) == null)
843                return defRetValue;
844            if (hasher.areEqual(k, curr))
845                return value[pos];
846        }
847    }
848
849
850    public V getOrDefault(final Object k, final V defaultValue) {
851        if (k == null)
852            return containsNullKey ? value[n] : defaultValue;
853        K curr;
854        final K[] key = this.key;
855        int pos;
856        // The starting point.
857        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
858            return defaultValue;
859        if (hasher.areEqual(k, curr))
860            return value[pos];
861        // There's always an unused entry.
862        while (true) {
863            if ((curr = key[pos = (pos + 1) & mask]) == null)
864                return defaultValue;
865            if (hasher.areEqual(k, curr))
866                return value[pos];
867        }
868    }
869
870    protected int positionOf(final Object k) {
871        if (k == null)
872        {
873            if(containsNullKey)
874                return n;
875            else
876                return -1;
877        }
878        K curr;
879        final K[] key = this.key;
880        int pos;
881        // The starting point.
882        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
883            return -1;
884        if (hasher.areEqual(k, curr))
885            return pos;
886        // There's always an unused entry.
887        while (true) {
888            if ((curr = key[pos = pos + 1 & mask]) == null)
889                return -1;
890            if (hasher.areEqual(k, curr))
891                return pos;
892        }
893    }
894
895    /**
896     * Gets the position in the ordering of the given key, though not as efficiently as some data structures can do it
897     * (e.g. {@link Arrangement} can access ordering position very quickly but doesn't store other values on its own).
898     * Returns a value that is at least 0 if it found k, or -1 if k was not present.
899     * @param k a key or possible key that this should find the index of
900     * @return the index of k, if present, or -1 if it is not present in this OrderedMap
901     */
902    public int indexOf(final Object k)
903    {
904        int pos = positionOf(k);
905        return (pos < 0) ? -1 : order.indexOf(pos);
906    }
907
908    /**
909     * Swaps the positions in the ordering for the given items, if they are both present. Returns true if the ordering
910     * changed as a result of this call, or false if it stayed the same (which can be because left or right was not
911     * present, or because left and right are the same reference (so swapping would do nothing)).
912     * @param left an item that should be present in this OrderedMap
913     * @param right an item that should be present in this OrderedMap
914     * @return true if this OrderedMap changed in ordering as a result of this call, or false otherwise
915     */
916    public boolean swap(final K left, final K right)
917    {
918        if(left == right) return false;
919        int l = indexOf(left);
920        if(l < 0) return false;
921        int r = indexOf(right);
922        if(r < 0) return false;
923        order.swap(l, r);
924        return true;
925    }
926    /**
927     * Swaps the given indices in the ordering, if they are both valid int indices. Returns true if the ordering
928     * changed as a result of this call, or false if it stayed the same (which can be because left or right referred to
929     * an out-of-bounds index, or because left and right are equal (so swapping would do nothing)).
930     * @param left an index of an item in this OrderedMap, at least 0 and less than {@link #size()}
931     * @param right an index of an item in this OrderedMap, at least 0 and less than {@link #size()}
932     * @return true if this OrderedMap changed in ordering as a result of this call, or false otherwise
933     */
934    public boolean swapIndices(final int left, final int right)
935    {
936        if(left < 0 || right < 0 || left >= order.size || right >= order.size || left == right) return false;
937        order.swap(left, right);
938        return true;
939    }
940
941
942    public boolean containsKey(final Object k) {
943        if (k == null)
944            return containsNullKey;
945        K curr;
946        final K[] key = this.key;
947        int pos;
948        // The starting point.
949        if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
950            return false;
951        if (hasher.areEqual(k, curr))
952            return true;
953        // There's always an unused entry.
954        while (true) {
955            if ((curr = key[pos = (pos + 1) & mask]) == null)
956                return false;
957            if (hasher.areEqual(k, curr))
958                return true;
959        }
960    }
961    public boolean containsValue(final Object v) {
962        final V[] value = this.value;
963        final K[] key = this.key;
964        if (containsNullKey
965                && (value[n] == null ? v == null : value[n].equals(v)))
966            return true;
967        for (int i = n; i-- != 0;)
968            if (key[i] != null
969                    && (value[i] == null ? v == null : value[i].equals(v)))
970                return true;
971        return false;
972    }
973    /*
974     * Removes all elements from this map.
975     *
976     * <P>To increase object reuse, this method does not change the table size.
977     * If you want to reduce the table size, you must use {@link #trim()}.
978     */
979    public void clear() {
980        if (size == 0)
981            return;
982        size = 0;
983        containsNullKey = false;
984        Arrays.fill(key, null);
985        Arrays.fill(value, null);
986        order.clear();
987    }
988
989    public int size() {
990        return size;
991    }
992
993    public boolean isEmpty() {
994        return size == 0;
995    }
996
997    /**
998     * The entry class for a OrderedMap does not record key and value, but rather the position in the hash table of the corresponding entry. This is necessary so that calls to
999     * {@link Entry#setValue(Object)} are reflected in the map
1000     */
1001    final class MapEntry
1002            implements
1003            Entry<K, V> {
1004        // The table index this entry refers to, or -1 if this entry has been
1005        // deleted.
1006        int index;
1007        MapEntry(final int index) {
1008            this.index = index;
1009        }
1010        MapEntry() {
1011        }
1012        public K getKey() {
1013            return key[index];
1014        }
1015        public V getValue() {
1016            return value[index];
1017        }
1018        public V setValue(final V v) {
1019            final V oldValue = value[index];
1020            value[index] = v;
1021            return oldValue;
1022        }
1023        @SuppressWarnings("unchecked")
1024        public boolean equals(final Object o) {
1025            if (!(o instanceof Map.Entry))
1026                return false;
1027            Map.Entry<K, V> e = (Map.Entry<K, V>) o;
1028            return (key[index] == null
1029                    ? e.getKey() == null
1030                    : hasher.areEqual(key[index], e.getKey()))
1031                    && (value[index] == null
1032                    ? e.getValue() == null
1033                    : value[index].equals(e.getValue()));
1034        }
1035        public int hashCode() {
1036            return hasher.hash(key[index])
1037                    ^ (value[index] == null ? 0 : value[index].hashCode());
1038        }
1039        @Override
1040        public String toString() {
1041            return (key[index] == OrderedMap.this ? "(this collection)" : String.valueOf(key[index]))
1042                    + "=>"
1043                    + (value[index] == OrderedMap.this ? "(this collection)" : String.valueOf(value[index]));
1044        }
1045    }
1046
1047    /**
1048     * Modifies the ordering so that the given entry is removed. This method will complete in linear time.
1049     *
1050     * @param i the index of an entry.
1051     * @return the iteration-order index of the removed entry
1052     */
1053    protected int fixOrder(final int i) {
1054        if (size == 0) {
1055            order.clear();
1056            return -1;
1057        }
1058        return order.removeValue(i);
1059    }
1060
1061    /**
1062     * Modifies the ordering for a shift from s to d.
1063     * <br>
1064     * This method will complete in linear time unless the source position is first or last.
1065     *
1066     * @param s the source position.
1067     * @param d the destination position.
1068     */
1069    protected void fixOrder(int s, int d) {
1070        if(size == 0)
1071            return;
1072        if (size == 1 || order.items[0] == s) {
1073            order.set(0, d);
1074        }
1075        else if (order.items[order.size-1] == s) {
1076            order.set(order.size - 1, d);
1077        }
1078        else
1079        {
1080            order.set(order.indexOf(s), d);
1081        }
1082    }
1083
1084    /**
1085     * Returns the first key of this map in iteration order.
1086     *
1087     * @return the first key in iteration order.
1088     */
1089    public K firstKey() {
1090        if (size == 0)
1091            throw new NoSuchElementException();
1092        return key[order.items[0]];
1093    }
1094    /**
1095     * Returns the last key of this map in iteration order.
1096     *
1097     * @return the last key in iteration order.
1098     */
1099    public K lastKey() {
1100        if (size == 0)
1101            throw new NoSuchElementException();
1102        return key[order.items[order.size-1]];
1103    }
1104    public Comparator<? super K> comparator() {
1105        return null;
1106    }
1107    public SortedMap<K, V> tailMap(K from) {
1108        throw new UnsupportedOperationException();
1109    }
1110    public SortedMap<K, V> headMap(K to) {
1111        throw new UnsupportedOperationException();
1112    }
1113    public SortedMap<K, V> subMap(K from, K to) {
1114        throw new UnsupportedOperationException();
1115    }
1116    /**
1117     * A list iterator over a OrderedMap.
1118     *
1119     * <P>
1120     * This class provides a list iterator over a OrderedMap. The
1121     * constructor runs in constant time.
1122     */
1123    private class MapIterator {
1124        /**
1125         * The entry that will be returned by the next call to
1126         * {@link java.util.ListIterator#previous()} (or <code>null</code> if no
1127         * previous entry exists).
1128         */
1129        int prev = -1;
1130        /**
1131         * The entry that will be returned by the next call to
1132         * {@link java.util.ListIterator#next()} (or <code>null</code> if no
1133         * next entry exists).
1134         */
1135        int next;
1136        /**
1137         * The last entry that was returned (or -1 if we did not iterate or used
1138         * {@link java.util.Iterator#remove()}).
1139         */
1140        int curr = -1;
1141        /**
1142         * The current index (in the sense of a {@link java.util.ListIterator}).
1143         * Note that this value is not meaningful when this iterator has been
1144         * created using the nonempty constructor.
1145         */
1146        int index;
1147        private MapIterator() {
1148            next = size == 0 ? -1 : order.items[0];
1149            index = 0;
1150        }
1151        public boolean hasNext() {
1152            return next != -1;
1153        }
1154        public boolean hasPrevious() {
1155            return prev != -1;
1156        }
1157        private void ensureIndexKnown() {
1158            if (index >= 0)
1159                return;
1160            if (prev == -1) {
1161                index = 0;
1162                return;
1163            }
1164            if (next == -1) {
1165                index = size;
1166                return;
1167            }
1168            index = 0;
1169        }
1170        public int nextIndex() {
1171            ensureIndexKnown();
1172            return index + 1;
1173        }
1174        public int previousIndex() {
1175            ensureIndexKnown();
1176            return index - 1;
1177        }
1178        public int nextEntry() {
1179            if (!hasNext())
1180                throw new NoSuchElementException();
1181            curr = next;
1182            if(++index >= order.size)
1183                next = -1;
1184            else
1185                next = order.get(index);//(int) link[curr];
1186            prev = curr;
1187            return curr;
1188        }
1189        public int previousEntry() {
1190            if (!hasPrevious())
1191                throw new NoSuchElementException();
1192            curr = prev;
1193            if(--index < 1)
1194                prev = -1;
1195            else
1196                prev = order.get(index - 1);
1197            next = curr;
1198            return curr;
1199        }
1200        public void remove() {
1201            ensureIndexKnown();
1202            if (curr == -1)
1203                throw new IllegalStateException();
1204            if (curr == prev) {
1205                /*
1206                 * If the last operation was a next(), we are removing an entry
1207                 * that precedes the current index, and thus we must decrement
1208                 * it.
1209                 */
1210                if(--index >= 1)
1211                    prev = order.get(index - 1); //(int) (link[curr] >>> 32);
1212                else
1213                    prev = -1;
1214            } else {
1215                if(index < order.size - 1)
1216                    next = order.get(index + 1);
1217                else
1218                    next = -1;
1219            }
1220            order.removeIndex(index);
1221            size--;
1222            int last, slot, pos = curr;
1223            curr = -1;
1224            if (pos == n) {
1225                containsNullKey = false;
1226                key[n] = null;
1227                value[n] = null;
1228            } else {
1229                K curr;
1230                final K[] key = OrderedMap.this.key;
1231                // We have to horribly duplicate the shiftKeys() code because we
1232                // need to update next/prev.
1233                for (;;) {
1234                    pos = ((last = pos) + 1) & mask;
1235                    for (;;) {
1236                        if ((curr = key[pos]) == null) {
1237                            key[last] = null;
1238                            value[last] = null;
1239                            return;
1240                        }
1241                        slot = (hasher.hash(curr)) & mask;
1242                        if (last <= pos
1243                                ? last >= slot || slot > pos
1244                                : last >= slot && slot > pos)
1245                            break;
1246                        pos = (pos + 1) & mask;
1247                    }
1248                    key[last] = curr;
1249                    value[last] = value[pos];
1250                    if (next == pos)
1251                        next = last;
1252                    if (prev == pos)
1253                        prev = last;
1254                    fixOrder(pos, last);
1255                }
1256            }
1257        }
1258        public int skip(final int n) {
1259            int i = n;
1260            while (i-- != 0 && hasNext())
1261                nextEntry();
1262            return n - i - 1;
1263        }
1264        public int back(final int n) {
1265            int i = n;
1266            while (i-- != 0 && hasPrevious())
1267                previousEntry();
1268            return n - i - 1;
1269        }
1270    }
1271    private class EntryIterator extends MapIterator
1272            implements
1273            Iterator<Entry<K, V>>, Serializable {
1274        private static final long serialVersionUID = 0L;
1275
1276        private MapEntry entry;
1277        public EntryIterator() {
1278        }
1279        public MapEntry next() {
1280            return entry = new MapEntry(nextEntry());
1281        }
1282        public MapEntry previous() {
1283            return entry = new MapEntry(previousEntry());
1284        }
1285        @Override
1286        public void remove() {
1287            super.remove();
1288            entry.index = -1; // You cannot use a deleted entry.
1289        }
1290        public void set(Entry<K, V> ok) {
1291            throw new UnsupportedOperationException();
1292        }
1293        public void add(Entry<K, V> ok) {
1294            throw new UnsupportedOperationException();
1295        }
1296    }
1297
1298    public final class MapEntrySet
1299            implements Cloneable, SortedSet<Entry<K, V>>, Set<Entry<K, V>>, Collection<Entry<K, V>>, Serializable {
1300        private static final long serialVersionUID = 0L;
1301        public EntryIterator iterator() {
1302            return new EntryIterator();
1303        }
1304        public Comparator<? super Entry<K, V>> comparator() {
1305            return null;
1306        }
1307        public SortedSet<Entry<K, V>> subSet(
1308                Entry<K, V> fromElement,
1309                Entry<K, V> toElement) {
1310            throw new UnsupportedOperationException();
1311        }
1312        public SortedSet<Entry<K, V>> headSet(
1313                Entry<K, V> toElement) {
1314            throw new UnsupportedOperationException();
1315        }
1316        public SortedSet<Entry<K, V>> tailSet(
1317                Entry<K, V> fromElement) {
1318            throw new UnsupportedOperationException();
1319        }
1320        public Entry<K, V> first() {
1321            if (size == 0)
1322                throw new NoSuchElementException();
1323            return new MapEntry(order.items[0]);
1324        }
1325        public Entry<K, V> last() {
1326            if (size == 0)
1327                throw new NoSuchElementException();
1328            return new MapEntry(order.items[order.size-1]);
1329        }
1330        @SuppressWarnings("unchecked")
1331        public boolean contains(final Object o) {
1332            if (!(o instanceof Map.Entry))
1333                return false;
1334            final Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1335            final K k = (K) e.getKey();
1336            final V v = (V) e.getValue();
1337            if (k == null)
1338                return containsNullKey
1339                        && (value[n] == null ? v == null : value[n]
1340                        .equals(v));
1341            K curr;
1342            final K[] key = OrderedMap.this.key;
1343            int pos;
1344            // The starting point.
1345            if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
1346                return false;
1347            if (hasher.areEqual(k, curr))
1348                return value[pos] == null ? v == null : value[pos]
1349                        .equals(v);
1350            // There's always an unused entry.
1351            while (true) {
1352                if ((curr = key[pos = (pos + 1) & mask]) == null)
1353                    return false;
1354                if (hasher.areEqual(k, curr))
1355                    return value[pos] == null ? v == null : value[pos]
1356                            .equals(v);
1357            }
1358        }
1359        @SuppressWarnings("unchecked")
1360        public boolean remove(final Object o) {
1361            if (!(o instanceof Map.Entry))
1362                return false;
1363            final Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1364            final K k = (K) e.getKey();
1365            final V v = (V) e.getValue();
1366            if (k == null) {
1367                if (containsNullKey
1368                        && (value[n] == null ? v == null : value[n]
1369                        .equals(v))) {
1370                    removeNullEntry();
1371                    return true;
1372                }
1373                return false;
1374            }
1375            K curr;
1376            final K[] key = OrderedMap.this.key;
1377            int pos;
1378            // The starting point.
1379            if ((curr = key[pos = (hasher.hash(k)) & mask]) == null)
1380                return false;
1381            if (hasher.areEqual(curr, k)) {
1382                if (value[pos] == null ? v == null : value[pos]
1383                        .equals(v)) {
1384                    removeEntry(pos);
1385                    return true;
1386                }
1387                return false;
1388            }
1389            while (true) {
1390                if ((curr = key[pos = (pos + 1) & mask]) == null)
1391                    return false;
1392                if (hasher.areEqual(curr, k)) {
1393                    if (value[pos] == null ? v == null : value[pos]
1394                            .equals(v)) {
1395                        removeEntry(pos);
1396                        return true;
1397                    }
1398                }
1399            }
1400        }
1401        public int size() {
1402            return size;
1403        }
1404        public void clear() {
1405            OrderedMap.this.clear();
1406        }
1407
1408        @Override
1409        public boolean equals(final Object o) {
1410            if (o == this)
1411                return true;
1412            if (!(o instanceof Set))
1413                return false;
1414            Set<?> s = (Set<?>) o;
1415            return s.size() == size() && containsAll(s);
1416        }
1417
1418        public Object[] toArray() {
1419            final Object[] a = new Object[size()];
1420            objectUnwrap(iterator(), a);
1421            return a;
1422        }
1423
1424        @SuppressWarnings("unchecked")
1425        public <T> T[] toArray(T[] a) {
1426            if (a == null || a.length < size()) a = (T[]) new Object[size()];
1427            objectUnwrap(iterator(), a);
1428            return a;
1429        }
1430
1431        /**
1432         * Unsupported.
1433         *
1434         * @param c ignored
1435         * @return nothing, throws UnsupportedOperationException
1436         * @throws UnsupportedOperationException always
1437         */
1438        public boolean addAll(Collection<? extends Entry<K, V>> c) {
1439            throw new UnsupportedOperationException("addAll not supported");
1440        }
1441
1442        /**
1443         * Unsupported.
1444         *
1445         * @param k ignored
1446         * @return nothing, throws UnsupportedOperationException
1447         * @throws UnsupportedOperationException always
1448         */
1449        public boolean add(Entry<K, V> k) {
1450            throw new UnsupportedOperationException("add not supported");
1451        }
1452
1453        /**
1454         * Checks whether this collection contains all elements from the given
1455         * collection.
1456         *
1457         * @param c a collection.
1458         * @return <code>true</code> if this collection contains all elements of the
1459         * argument.
1460         */
1461        public boolean containsAll(Collection<?> c) {
1462            int n = c.size();
1463            final Iterator<?> i = c.iterator();
1464            while (n-- != 0)
1465                if (!contains(i.next()))
1466                    return false;
1467            return true;
1468        }
1469
1470        /**
1471         * Retains in this collection only elements from the given collection.
1472         *
1473         * @param c a collection.
1474         * @return <code>true</code> if this collection changed as a result of the
1475         * call.
1476         */
1477        public boolean retainAll(Collection<?> c) {
1478            boolean retVal = false;
1479            int n = size();
1480            final Iterator<?> i = iterator();
1481            while (n-- != 0) {
1482                if (!c.contains(i.next())) {
1483                    i.remove();
1484                    retVal = true;
1485                }
1486            }
1487            return retVal;
1488        }
1489
1490        /**
1491         * Remove from this collection all elements in the given collection. If the
1492         * collection is an instance of this class, it uses faster iterators.
1493         *
1494         * @param c a collection.
1495         * @return <code>true</code> if this collection changed as a result of the
1496         * call.
1497         */
1498        public boolean removeAll(Collection<?> c) {
1499            boolean retVal = false;
1500            int n = c.size();
1501            final Iterator<?> i = c.iterator();
1502            while (n-- != 0)
1503                if (remove(i.next()))
1504                    retVal = true;
1505            return retVal;
1506        }
1507
1508        public boolean isEmpty() {
1509            return size() == 0;
1510        }
1511
1512        @Override
1513        public String toString() {
1514            final StringBuilder s = new StringBuilder();
1515            final EntryIterator i = iterator();
1516            int n = size();
1517            MapEntry k;
1518            boolean first = true;
1519            s.append("{");
1520            while (n-- != 0) {
1521                if (first)
1522                    first = false;
1523                else
1524                    s.append(", ");
1525                k = i.next();
1526                s.append(key[k.index] == OrderedMap.this ? "(this collection)" : String.valueOf(key[k.index]))
1527                        .append("=>")
1528                        .append(value[k.index] == OrderedMap.this ? "(this collection)" : String.valueOf(value[k.index]));
1529            }
1530            s.append("}");
1531            return s.toString();
1532        }
1533
1534    }
1535
1536    @Override
1537    public SortedSet<Entry<K,V>> entrySet() {
1538        if (entries == null) entries = new MapEntrySet();
1539        return entries;
1540    }
1541
1542    /**
1543     * An iterator on keys.
1544     * <p>
1545     * <P>We simply override the {@link ListIterator#next()}/{@link ListIterator#previous()} methods (and possibly their type-specific counterparts) so that they return keys
1546     * instead of entries.
1547     */
1548    public final class KeyIterator extends MapIterator implements Iterator<K>, Serializable {
1549        private static final long serialVersionUID = 0L;
1550        public K previous() {
1551            return key[previousEntry()];
1552        }
1553        public void set(K k) {
1554            throw new UnsupportedOperationException();
1555        }
1556        public void add(K k) {
1557            throw new UnsupportedOperationException();
1558        }
1559        public KeyIterator() {}
1560        public K next() {
1561            return key[nextEntry()];
1562        }
1563        public void remove() { super.remove(); }
1564    }
1565
1566    public final class KeySet implements SortedSet<K>, Serializable {
1567        private static final long serialVersionUID = 0L;
1568
1569        public KeyIterator iterator() {
1570            return new KeyIterator();
1571        }
1572
1573        public int size() {
1574            return size;
1575        }
1576
1577        public void clear() {
1578            OrderedMap.this.clear();
1579        }
1580
1581        public K first() {
1582            if (size == 0) throw new NoSuchElementException();
1583            return key[order.items[0]];
1584        }
1585
1586        public K last() {
1587            if (size == 0) throw new NoSuchElementException();
1588            return key[order.items[order.size-1]];
1589        }
1590
1591        public Comparator<K> comparator() {
1592            return null;
1593        }
1594
1595        public final SortedSet<K> tailSet(K from) {
1596            throw new UnsupportedOperationException();
1597        }
1598
1599        public final SortedSet<K> headSet(K to) {
1600            throw new UnsupportedOperationException();
1601        }
1602
1603        public final SortedSet<K> subSet(K from, K to) {
1604            throw new UnsupportedOperationException();
1605        }
1606
1607        @SuppressWarnings("unchecked")
1608        @Override
1609        public <T> T[] toArray(T[] a) {
1610            if (a == null || a.length < size()) a = (T[]) new Object[size()];
1611            unwrap(iterator(), a);
1612            return a;
1613        }
1614
1615        /**
1616         * Always throws an UnsupportedOperationException
1617         */
1618        public boolean remove(Object ok) {
1619            throw new UnsupportedOperationException("Cannot remove from the key set directly");
1620        }
1621
1622        /**
1623         * Always throws an UnsupportedOperationException
1624         */
1625        public boolean add(final K o) {
1626            throw new UnsupportedOperationException("Cannot add to the key set directly");
1627        }
1628
1629        /**
1630         * Delegates to the corresponding type-specific method.
1631         */
1632        public boolean contains(final Object o) {
1633            return containsKey(o);
1634        }
1635
1636        /**
1637         * Checks whether this collection contains all elements from the given type-specific collection.
1638         *
1639         * @param c a type-specific collection.
1640         * @return <code>true</code> if this collection contains all elements of the argument.
1641         */
1642        public boolean containsAll(Collection<?> c) {
1643            final Iterator<?> i = c.iterator();
1644            int n = c.size();
1645            while (n-- != 0)
1646                if (!contains(i.next())) return false;
1647            return true;
1648        }
1649
1650        /**
1651         * Retains in this collection only elements from the given type-specific collection.
1652         *
1653         * @param c a type-specific collection.
1654         * @return <code>true</code> if this collection changed as a result of the call.
1655         */
1656        public boolean retainAll(Collection<?> c) {
1657            boolean retVal = false;
1658            int n = size();
1659            final Iterator<?> i = iterator();
1660            while (n-- != 0) {
1661                if (!c.contains(i.next())) {
1662                    i.remove();
1663                    retVal = true;
1664                }
1665            }
1666            return retVal;
1667        }
1668
1669        /**
1670         * Remove from this collection all elements in the given type-specific collection.
1671         *
1672         * @param c a type-specific collection.
1673         * @return <code>true</code> if this collection changed as a result of the call.
1674         */
1675        public boolean removeAll(Collection<?> c) {
1676            boolean retVal = false;
1677            int n = c.size();
1678            final Iterator<?> i = c.iterator();
1679            while (n-- != 0)
1680                if (remove(i.next())) retVal = true;
1681            return false;
1682        }
1683
1684        public Object[] toArray() {
1685            final Object[] a = new Object[size()];
1686            objectUnwrap(iterator(), a);
1687            return a;
1688        }
1689
1690        /**
1691         * Adds all elements of the given collection to this collection.
1692         *
1693         * @param c a collection.
1694         * @return <code>true</code> if this collection changed as a result of the call.
1695         */
1696        public boolean addAll(Collection<? extends K> c) {
1697            boolean retVal = false;
1698            final Iterator<? extends K> i = c.iterator();
1699            int n = c.size();
1700            while (n-- != 0)
1701                if (add(i.next())) retVal = true;
1702            return false;
1703        }
1704
1705        @Override
1706        public boolean equals(final Object o) {
1707            if (o == this)
1708                return true;
1709            if (!(o instanceof Set))
1710                return false;
1711            Set<?> s = (Set<?>) o;
1712            if (s.size() != size())
1713                return false;
1714            return containsAll(s);
1715        }
1716        /**
1717         * Unwraps an iterator into an array starting at a given offset for a given number of elements.
1718         * <p>
1719         * <P>This method iterates over the given type-specific iterator and stores the elements returned, up to a maximum of <code>length</code>, in the given array starting at <code>offset</code>. The
1720         * number of actually unwrapped elements is returned (it may be less than <code>max</code> if the iterator emits less than <code>max</code> elements).
1721         *
1722         * @param i      a type-specific iterator.
1723         * @param array  an array to contain the output of the iterator.
1724         * @param offset the first element of the array to be returned.
1725         * @param max    the maximum number of elements to unwrap.
1726         * @return the number of elements unwrapped.
1727         */
1728        public int unwrap(final KeyIterator i, final Object[] array, int offset, final int max) {
1729            if (max < 0) throw new IllegalArgumentException("The maximum number of elements (" + max + ") is negative");
1730            if (offset < 0 || offset + max > array.length) throw new IllegalArgumentException();
1731            int j = max;
1732            while (j-- != 0 && i.hasNext())
1733                array[offset++] = i.next();
1734            return max - j - 1;
1735        }
1736
1737        /**
1738         * Unwraps an iterator into an array.
1739         * <p>
1740         * <P>This method iterates over the given type-specific iterator and stores the elements returned in the given array. The iteration will stop when the iterator has no more elements or when the end
1741         * of the array has been reached.
1742         *
1743         * @param i     a type-specific iterator.
1744         * @param array an array to contain the output of the iterator.
1745         * @return the number of elements unwrapped.
1746         */
1747        public int unwrap(final KeyIterator i, final Object[] array) {
1748            return unwrap(i, array, 0, array.length);
1749        }
1750
1751        public boolean isEmpty() {
1752            return size() == 0;
1753        }
1754
1755        @Override
1756        public String toString() {
1757            final StringBuilder s = new StringBuilder();
1758            int n = size();
1759            boolean first = true;
1760            s.append("{");
1761            for (int i = 0; i < n; i++) {
1762                if (first) first = false;
1763                else s.append(", ");
1764                K k = keyAt(i);
1765                s.append(k == OrderedMap.this ? "(this collection)" : String.valueOf(k));
1766            }
1767            s.append("}");
1768            return s.toString();
1769        }
1770    }
1771
1772    public SortedSet<K> keySet() {
1773        if (keys == null) keys = new KeySet();
1774        return keys;
1775    }
1776
1777    public OrderedSet<K> keysAsOrderedSet()
1778    {
1779        OrderedSet<K> os = new OrderedSet<>(size, f, hasher);
1780        for (int i = 0; i < size; i++) {
1781            os.add(keyAt(i));
1782        }
1783        return os;
1784    }
1785
1786    /**
1787     * An iterator on values.
1788     * <p>
1789     * <P>We simply override the {@link ListIterator#next()}/{@link ListIterator#previous()} methods (and possibly their type-specific counterparts) so that they return values
1790     * instead of entries.
1791     */
1792    public final class ValueIterator extends MapIterator implements ListIterator<V>, Serializable {
1793        private static final long serialVersionUID = 0L;
1794
1795        public V previous() {
1796            return value[previousEntry()];
1797        }
1798        public void set(V v) {
1799            throw new UnsupportedOperationException();
1800        }
1801        public void add(V v) {
1802            throw new UnsupportedOperationException();
1803        }
1804        public ValueIterator() {}
1805        public V next() {
1806            return value[nextEntry()];
1807        }
1808        public void remove() { super.remove(); }
1809    }
1810    public final class ValueCollection extends AbstractCollection<V> implements Serializable
1811    {
1812        private static final long serialVersionUID = 0L;
1813        public ValueIterator iterator() {
1814            return new ValueIterator();
1815        }
1816        public int size() {
1817            return size;
1818        }
1819        public boolean contains(Object v) {
1820            return containsValue(v);
1821        }
1822        public void clear() {
1823            OrderedMap.this.clear();
1824        }
1825    }
1826    public Collection<V> values() {
1827        if (values == null) values = new ValueCollection();
1828        return values;
1829    }
1830
1831    public ArrayList<V> valuesAsList()
1832    {
1833        ArrayList<V> ls = new ArrayList<>(size);
1834        for (int i = 0; i < size; i++) {
1835            ls.add(getAt(i));
1836        }
1837        return ls;
1838    }
1839
1840    /**
1841     * Rehashes the map, making the table as small as possible.
1842     * <p>
1843     * <P>This method rehashes the table to the smallest size satisfying the load factor. It can be used when the set will not be changed anymore, so to optimize access speed and size.
1844     * <p>
1845     * <P>If the table size is already the minimum possible, this method does nothing.
1846     *
1847     * @return true if there was enough memory to trim the map.
1848     * @see #trim(int)
1849     */
1850    public boolean trim() {
1851        final int l = arraySize(size, f);
1852        if (l >= n || size > maxFill(l, f)) return true;
1853        try {
1854            rehash(l);
1855        } catch (Exception cantDoIt) {
1856            return false;
1857        }
1858        return true;
1859    }
1860
1861    /**
1862     * Rehashes this map if the table is too large.
1863     * <p>
1864     * <P>Let <var>N</var> be the smallest table size that can hold <code>max(n,{@link #size()})</code> entries, still satisfying the load factor. If the current table size is smaller than or equal to
1865     * <var>N</var>, this method does nothing. Otherwise, it rehashes this map in a table of size <var>N</var>.
1866     * <p>
1867     * <P>This method is useful when reusing maps. {@linkplain #clear() Clearing a map} leaves the table size untouched. If you are reusing a map many times, you can call this method with a typical
1868     * size to avoid keeping around a very large table just because of a few large transient maps.
1869     *
1870     * @param n the threshold for the trimming.
1871     * @return true if there was enough memory to trim the map.
1872     * @see #trim()
1873     */
1874    public boolean trim(final int n) {
1875        final int l = HashCommon.nextPowerOfTwo((int) Math.ceil(n / f));
1876        if (l >= n || size > maxFill(l, f)) return true;
1877        try {
1878            rehash(l);
1879        } catch (Exception cantDoIt) {
1880            return false;
1881        }
1882        return true;
1883    }
1884
1885    /**
1886     * Rehashes the map.
1887     *
1888     * <P>
1889     * This method implements the basic rehashing strategy, and may be overriden
1890     * by subclasses implementing different rehashing strategies (e.g.,
1891     * disk-based rehashing). However, you should not override this method
1892     * unless you understand the internal workings of this class.
1893     *
1894     * @param newN
1895     *            the new size
1896     */
1897
1898    @SuppressWarnings("unchecked")
1899    protected void rehash(final int newN) {
1900        final K[] key = this.key;
1901        final V[] value = this.value;
1902        final int mask = newN - 1;
1903        final K[] newKey = (K[]) new Object[newN + 1];
1904        final V[] newValue = (V[]) new Object[newN + 1];
1905        final int sz = order.size;
1906        K k;
1907        int i, pos;
1908        final int[] oi = order.items;
1909        for (int q = 0; q < sz; q++) {
1910            i = oi[q];
1911            if ((k = key[i]) == null)
1912                pos = newN;
1913            else {
1914                pos = (hasher.hash(k)) & mask;
1915                while (newKey[pos] != null)
1916                    pos = (pos + 1) & mask;
1917            }
1918            newKey[pos] = k;
1919            newValue[pos] = value[i];
1920            oi[q] = pos;
1921        }
1922        n = newN;
1923        this.mask = mask;
1924        maxFill = maxFill(n, f);
1925        this.key = newKey;
1926        this.value = newValue;
1927    }
1928    /*
1929    @SuppressWarnings("unchecked")
1930    protected void rehash(final int newN) {
1931        final K key[] = this.key;
1932        final V value[] = this.value;
1933        final int mask = newN - 1; // Note that this is used by the hashing
1934        // macro
1935        final K newKey[] = (K[]) new Object[newN + 1];
1936        final V newValue[] = (V[]) new Object[newN + 1];
1937        int i = first, prev = -1, newPrev = -1, t, pos;
1938        final long link[] = this.link;
1939        final long newLink[] = new long[newN + 1];
1940        first = -1;
1941        for (int j = size; j-- != 0;) {
1942            if (((key[i]) == null))
1943                pos = newN;
1944            else {
1945                pos = (((key[i]).hashCode())) & mask;
1946                while (!((newKey[pos]) == null))
1947                    pos = (pos + 1) & mask;
1948            }
1949            newKey[pos] = key[i];
1950            newValue[pos] = value[i];
1951            if (prev != -1) {
1952                newLink[newPrev] ^= ((newLink[newPrev] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
1953                newLink[pos] ^= ((newLink[pos] ^ ((newPrev & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
1954                newPrev = pos;
1955            } else {
1956                newPrev = first = pos;
1957                // Special case of SET(newLink[ pos ], -1, -1);
1958                newLink[pos] = -1L;
1959            }
1960            t = i;
1961            i = (int) link[i];
1962            prev = t;
1963        }
1964        this.link = newLink;
1965        this.last = newPrev;
1966        if (newPrev != -1)
1967            // Special case of SET_NEXT( newLink[ newPrev ], -1 );
1968            newLink[newPrev] |= -1 & 0xFFFFFFFFL;
1969        n = newN;
1970        this.mask = mask;
1971        maxFill = maxFill(n, f);
1972        this.key = newKey;
1973        this.value = newValue;
1974    }
1975    */
1976    /**
1977     * Returns a deep copy of this map.
1978     *
1979     * <P>
1980     * This method performs a deep copy of this OrderedMap; the data stored in the
1981     * map, however, is not cloned. Note that this makes a difference only for
1982     * object keys.
1983     *
1984     * @return a deep copy of this map.
1985     */
1986    @SuppressWarnings("unchecked")
1987    @GwtIncompatible
1988    public OrderedMap<K, V> clone() {
1989        OrderedMap<K, V> c;
1990        try {
1991            c = new OrderedMap<>(hasher);
1992            c.key = (K[]) new Object[n + 1];
1993            System.arraycopy(key, 0, c.key, 0, n + 1);
1994            c.value = (V[]) new Object[n + 1];
1995            System.arraycopy(value, 0, c.value, 0, n + 1);
1996            c.order = (IntVLA) order.clone();
1997            return c;
1998        } catch (Exception cantHappen) {
1999            throw new UnsupportedOperationException(cantHappen + (cantHappen.getMessage() != null ?
2000                    "; " + cantHappen.getMessage() : ""));
2001        }
2002    }
2003    /**
2004     * Returns a hash code for this map.
2005     *
2006     * This method overrides the generic method provided by the superclass.
2007     * Since <code>equals()</code> is not overriden, it is important that the
2008     * value returned by this method is the same value as the one returned by
2009     * the overriden method.
2010     *
2011     * @return a hash code for this map.
2012     */
2013    public int hashCode() {
2014        int h = 0;
2015        for (int j = realSize(), i = 0, t = 0; j-- != 0;) {
2016            while (key[i] == null)
2017                i++;
2018            if (this != key[i])
2019                t = hasher.hash(key[i]);
2020            if (this != value[i])
2021                t ^= value[i] == null ? 0 : value[i].hashCode();
2022            h += t;
2023            i++;
2024        }
2025        // Zero / null keys have hash zero.
2026        if (containsNullKey)
2027            h += value[n] == null ? 0 : value[n].hashCode();
2028        return h;
2029    }
2030
2031    public long hash64()
2032    {
2033        return 31L * (31L * CrossHash.hash64(key) + CrossHash.hash64(value)) + size;
2034    }
2035    /**
2036     * Returns the maximum number of entries that can be filled before rehashing.
2037     *
2038     * @param n the size of the backing array.
2039     * @param f the load factor.
2040     * @return the maximum number of entries before rehashing.
2041     */
2042    public static int maxFill(final int n, final float f) {
2043        /* We must guarantee that there is always at least
2044         * one free entry (even with pathological load factors). */
2045        return Math.min((int)(n * f + 0.99999994f), n - 1);
2046    }
2047
2048    /**
2049     * Returns the least power of two smaller than or equal to 2<sup>30</sup> and larger than or equal to <code>Math.ceil( expected / f )</code>.
2050     *
2051     * @param expected the expected number of elements in a hash table.
2052     * @param f        the load factor.
2053     * @return the minimum possible size for a backing array.
2054     * @throws IllegalArgumentException if the necessary size is larger than 2<sup>30</sup>.
2055     */
2056    public static int arraySize(final int expected, final float f) {
2057        final long s = Math.max(2, HashCommon.nextPowerOfTwo((long) Math.ceil(expected / f)));
2058        if (s > (1 << 30))
2059            throw new IllegalArgumentException("Too large (" + expected + " expected elements with load factor " + f + ")");
2060        return (int) s;
2061    }
2062
2063    /**
2064     * Unwraps an iterator into an array starting at a given offset for a given number of elements.
2065     * <p>
2066     * <P>This method iterates over the given type-specific iterator and stores the elements returned, up to a maximum of <code>length</code>, in the given array starting at <code>offset</code>. The
2067     * number of actually unwrapped elements is returned (it may be less than <code>max</code> if the iterator emits less than <code>max</code> elements).
2068     *
2069     * @param i      a type-specific iterator.
2070     * @param array  an array to contain the output of the iterator.
2071     * @param offset the first element of the array to be returned.
2072     * @param max    the maximum number of elements to unwrap.
2073     * @return the number of elements unwrapped.
2074     */
2075    protected int unwrap(final ValueIterator i, final Object[] array, int offset, final int max) {
2076        if (max < 0) throw new IllegalArgumentException("The maximum number of elements (" + max + ") is negative");
2077        if (offset < 0 || offset + max > array.length) throw new IllegalArgumentException();
2078        int j = max;
2079        while (j-- != 0 && i.hasNext())
2080            array[offset++] = i.next();
2081        return max - j - 1;
2082    }
2083
2084    /**
2085     * Unwraps an iterator into an array.
2086     * <p>
2087     * <P>This method iterates over the given type-specific iterator and stores the elements returned in the given array. The iteration will stop when the iterator has no more elements or when the end
2088     * of the array has been reached.
2089     *
2090     * @param i     a type-specific iterator.
2091     * @param array an array to contain the output of the iterator.
2092     * @return the number of elements unwrapped.
2093     */
2094    protected int unwrap(final ValueIterator i, final Object[] array) {
2095        return unwrap(i, array, 0, array.length);
2096    }
2097
2098
2099    /** Unwraps an iterator into an array starting at a given offset for a given number of elements.
2100     *
2101     * <P>This method iterates over the given type-specific iterator and stores the elements returned, up to a maximum of <code>length</code>, in the given array starting at <code>offset</code>. The
2102     * number of actually unwrapped elements is returned (it may be less than <code>max</code> if the iterator emits less than <code>max</code> elements).
2103     *
2104     * @param i a type-specific iterator.
2105     * @param array an array to contain the output of the iterator.
2106     * @param offset the first element of the array to be returned.
2107     * @param max the maximum number of elements to unwrap.
2108     * @return the number of elements unwrapped. */
2109    protected static <K> int objectUnwrap(final Iterator<? extends K> i, final K[] array, int offset, final int max ) {
2110        if ( max < 0 ) throw new IllegalArgumentException( "The maximum number of elements (" + max + ") is negative" );
2111        if ( offset < 0 || offset + max > array.length ) throw new IllegalArgumentException();
2112        int j = max;
2113        while ( j-- != 0 && i.hasNext() )
2114            array[ offset++ ] = i.next();
2115        return max - j - 1;
2116    }
2117
2118    /** Unwraps an iterator into an array.
2119     *
2120     * <P>This method iterates over the given type-specific iterator and stores the elements returned in the given array. The iteration will stop when the iterator has no more elements or when the end
2121     * of the array has been reached.
2122     *
2123     * @param i a type-specific iterator.
2124     * @param array an array to contain the output of the iterator.
2125     * @return the number of elements unwrapped. */
2126    protected static <K> int objectUnwrap(final Iterator<? extends K> i, final K[] array) {
2127        return objectUnwrap(i, array, 0, array.length );
2128    }
2129
2130    @Override
2131    public String toString() {
2132        final StringBuilder s = new StringBuilder();
2133        int n = size(), i = 0;
2134        boolean first = true;
2135        K k;
2136        V v;
2137        s.append("OrderedMap{");
2138        while (i < n) {
2139            if (first) first = false;
2140            else s.append(", ");
2141            k = keyAt(i);
2142            v = getAt(i++);
2143            s.append(k == this ? "(this collection)" : String.valueOf(k))
2144                    .append("=>")
2145                    .append(v == this ? "(this collection)" : String.valueOf(v));
2146        }
2147        s.append("}");
2148        return s.toString();
2149    }
2150    @Override
2151    public boolean equals(Object o) {
2152        if (o == this)
2153            return true;
2154        if (!(o instanceof Map))
2155            return false;
2156        Map<?, ?> m = (Map<?, ?>) o;
2157        if (m.size() != size())
2158            return false;
2159        return entrySet().containsAll(m.entrySet());
2160    }
2161
2162    @GwtIncompatible
2163    private void writeObject(java.io.ObjectOutputStream s)
2164            throws java.io.IOException {
2165        final K[] key = this.key;
2166        final V[] value = this.value;
2167        final MapIterator i = new MapIterator();
2168        s.defaultWriteObject();
2169        for (int j = size, e; j-- != 0;) {
2170            e = i.nextEntry();
2171            s.writeObject(key[e]);
2172            s.writeObject(value[e]);
2173        }
2174    }
2175    @GwtIncompatible
2176    @SuppressWarnings("unchecked")
2177    private void readObject(java.io.ObjectInputStream s)
2178            throws java.io.IOException, ClassNotFoundException {
2179        s.defaultReadObject();
2180        n = arraySize(size, f);
2181        maxFill = maxFill(n, f);
2182        mask = n - 1;
2183        final K[] key = this.key = (K[]) new Object[n + 1];
2184        final V[] value = this.value = (V[]) new Object[n + 1];
2185        final IntVLA order = this.order = new IntVLA(n + 1);
2186        K k;
2187        V v;
2188        for (int i = size, pos; i-- != 0;) {
2189            k = (K) s.readObject();
2190            v = (V) s.readObject();
2191            if (k == null) {
2192                pos = n;
2193                containsNullKey = true;
2194            } else {
2195                pos = (hasher.hash(k))
2196                        & mask;
2197                while (!(key[pos] == null))
2198                    pos = (pos + 1) & mask;
2199            }
2200
2201            key[pos] = k;
2202            value[pos] = v;
2203            order.add(pos);
2204        }
2205    }
2206
2207    /**
2208     * Gets the value at the given index in the iteration order in constant time (random-access).
2209     * @param idx the index in the iteration order of the value to fetch
2210     * @return the value at the index, if the index is valid, otherwise the default return value
2211     */
2212    public V getAt(final int idx) {
2213        int pos;
2214        if (idx < 0 || idx >= order.size)
2215            return defRetValue;
2216        // The starting point.
2217        if (key[pos = order.get(idx)] == null)
2218            return containsNullKey ? value[n] : defRetValue;
2219        return value[pos];
2220    }
2221    /**
2222     * Gets the key at the given index in the iteration order in constant time (random-access).
2223     * @param idx the index in the iteration order of the key to fetch
2224     * @return the key at the index, if the index is valid, otherwise null
2225     */
2226    public K keyAt(final int idx) {
2227        if (idx < 0 || idx >= order.size)
2228            return null;
2229        // The starting point.
2230        return key[order.get(idx)];
2231    }
2232
2233    /**
2234     * Gets the key-value Map.Entry at the given index in the iteration order in constant time (random-access).
2235     * @param idx the index in the iteration order of the entry to fetch
2236     * @return the key-value entry at the index, if the index is valid, otherwise null
2237     */
2238    public Entry<K, V> entryAt(final int idx)
2239    {
2240        if (idx < 0 || idx >= order.size)
2241            return null;
2242        return new MapEntry(order.get(idx));
2243    }
2244
2245    /**
2246     * Removes the key and value at the given index in the iteration order in not-exactly constant time (though it still
2247     * should be efficient).
2248     * @param idx the index in the iteration order of the key and value to remove
2249     * @return the value removed, if there was anything removed, or the default return value otherwise (often null)
2250     */
2251    public V removeAt(final int idx) {
2252
2253        if (idx < 0 || idx >= order.size)
2254            return defRetValue;
2255        int pos = order.get(idx);
2256        if (key[pos] == null) {
2257            if (containsNullKey)
2258                return removeNullEntry();
2259            return defRetValue;
2260        }
2261        return removeEntry(pos);
2262    }
2263    /**
2264     * Gets a random value from this OrderedMap in constant time, using the given IRNG to generate a random number.
2265     * @param rng used to generate a random index for a value
2266     * @return a random value from this OrderedMap
2267     */
2268    public V randomValue(IRNG rng)
2269    {
2270        return getAt(rng.nextInt(order.size));
2271    }
2272
2273    /**
2274     * Gets a random key from this OrderedMap in constant time, using the given IRNG to generate a random number.
2275     * @param rng used to generate a random index for a key
2276     * @return a random key from this OrderedMap
2277     */
2278    public K randomKey(IRNG rng)
2279    {
2280        return keyAt(rng.nextInt(order.size));
2281    }
2282
2283    /**
2284     * Gets a random entry from this OrderedMap in constant time, using the given IRNG to generate a random number.
2285     * @param rng used to generate a random index for a entry
2286     * @return a random key-value entry from this OrderedMap
2287     */
2288    public Entry<K, V> randomEntry(IRNG rng)
2289    {
2290        return new MapEntry(order.getRandomElement(rng));
2291    }
2292
2293    /**
2294     * Randomly alters the iteration order for this OrderedMap using the given IRNG to shuffle.
2295     * @param rng used to generate a random ordering
2296     * @return this for chaining
2297     */
2298    public OrderedMap<K, V> shuffle(IRNG rng)
2299    {
2300        if(size < 2)
2301            return this;
2302        order.shuffle(rng);
2303        return this;
2304    }
2305
2306    /**
2307     * Given an array or varargs of replacement indices for this OrderedMap's iteration order, reorders this so the
2308     * first item in the returned version is the same as {@code getAt(ordering[0])} (with some care taken for negative
2309     * or too-large indices), the second item in the returned version is the same as {@code getAt(ordering[1])}, etc.
2310     * <br>
2311     * Negative indices are considered reversed distances from the end of ordering, so -1 refers to the same index as
2312     * {@code ordering[ordering.length - 1]}. If ordering is smaller than {@code size()}, only the indices up to the
2313     * length of ordering will be modified. If ordering is larger than {@code size()}, only as many indices will be
2314     * affected as {@code size()}, and reversed distances are measured from the end of this Map's entries instead of
2315     * the end of ordering. Duplicate values in ordering will produce duplicate values in the returned Map.
2316     * <br>
2317     * This method modifies this OrderedMap in-place and also returns it for chaining.
2318     * @param ordering an array or varargs of int indices, where the nth item in ordering changes the nth item in this
2319     *                 Map to have the value currently in this Map at the index specified by the value in ordering
2320     * @return this for chaining, after modifying it in-place
2321     */
2322    public OrderedMap<K, V> reorder(int... ordering)
2323    {
2324        order.reorder(ordering);
2325        return this;
2326    }
2327    private int alterEntry(final int pos) {
2328        int idx = fixOrder(pos);
2329        value[pos] = null;
2330        size--;
2331        shiftKeys(pos);
2332        return idx;
2333    }
2334    private int alterNullEntry() {
2335        int idx = fixOrder(n);
2336        containsNullKey = false;
2337        value[n] = null;
2338        size--;
2339        return idx;
2340    }
2341    /**
2342     * Swaps a key, original, for another key, replacement, while keeping replacement at the same point in the iteration
2343     * order as original and keeping it associated with the same value (which also keeps its iteration index). Unlike
2344     * the similar method {@link #alter(Object, Object)}, this will not change this OrderedMap if replacement is already
2345     * present. To contrast, alter() can reduce the size of the OrderedMap if both original and replacement are already
2346     * in the Map. If replacement is found, this returns the default return value, otherwise it switches out original
2347     * for replacement and returns whatever was associated with original.
2348     * @param original the key to find and swap out
2349     * @param replacement the key to replace original with
2350     * @return the value associated with original before, and replacement now
2351     */
2352    public V alterCarefully(final K original, final K replacement) {
2353        if(!containsKey(replacement))
2354            return alter(original, replacement);
2355        else
2356            return defRetValue;
2357    }
2358    /**
2359     * Swaps a key, original, for another key, replacement, while keeping replacement at the same point in the iteration
2360     * order as original and keeping it associated with the same value (which also keeps its iteration index).
2361     * Be aware that if both original and replacement are present in the OrderedMap, this will still replace original
2362     * with replacement but will also remove the other occurrence of replacement to avoid duplicate keys. This can throw
2363     * off the expected order because the duplicate could be at any point in the ordering when it is removed. You may
2364     * want to prefer {@link #alterCarefully(Object, Object)} if you don't feel like checking by hand for whether
2365     * replacement is already present, but using this method is perfectly reasonable if you know overlaps won't happen.
2366     * @param original the key to find and swap out
2367     * @param replacement the key to replace original with
2368     * @return the value associated with original before, and replacement now
2369     */
2370    public V alter(final K original, final K replacement) {
2371        V v;
2372        int idx;
2373        if (original == null) {
2374            if (containsNullKey) {
2375                v = value[n];
2376                idx = alterNullEntry();
2377                putAt(replacement, v, idx);
2378                return v;
2379            }
2380            else
2381                v = defRetValue;
2382            return v;
2383        }
2384        K curr;
2385        final K[] key = this.key;
2386        int pos;
2387        // The starting point.
2388        if ((curr = key[pos = (hasher.hash(original)) & mask]) == null)
2389            return defRetValue;
2390        if (hasher.areEqual(original, curr))
2391        {
2392            v = value[pos];
2393            idx = alterEntry(pos);
2394            putAt(replacement, v, idx);
2395            return v;
2396        }
2397        while (true) {
2398            if ((curr = key[pos = (pos + 1) & mask]) == null)
2399                return defRetValue;
2400            if (hasher.areEqual(original, curr))
2401            {
2402                v = value[pos];
2403                idx = alterEntry(pos);
2404                putAt(replacement, v, idx);
2405                return v;
2406            }
2407        }
2408    }
2409
2410    public List<V> getMany(Collection<K> keys)
2411    {
2412        if(keys == null)
2413            return new ArrayList<>(1);
2414        ArrayList<V> vals = new ArrayList<>(keys.size());
2415        for(K k : keys)
2416        {
2417            vals.add(get(k));
2418        }
2419        return vals;
2420    }
2421    /**
2422     * Changes the K at the given index to replacement while keeping replacement at the same point in the ordering.
2423     * Be aware that if replacement is present in the OrderedMap, this will still replace the given index
2424     * with replacement but will also remove the other occurrence of replacement to avoid duplicate keys. This can throw
2425     * off the expected order because the duplicate could be at any point in the ordering when it is removed. You may
2426     * want to prefer {@link #alterAtCarefully(int, Object)} if you don't feel like checking by hand for whether
2427     * replacement is already present, but using this method is perfectly reasonable if you know overlaps won't happen.
2428     * @param index       an index to replace the K key at
2429     * @param replacement another K key that will replace the original at the remembered index
2430     * @return the value associated with the possibly-altered key
2431     */
2432    public V alterAt(int index, K replacement)
2433    {
2434        return alter(keyAt(index), replacement);
2435    }
2436    /**
2437     * Changes the K at the given index to replacement while keeping replacement at the same point in the ordering.
2438     * Unlike the similar method {@link #alterAt(int, Object)}, this will not change this OrderedMap if replacement is
2439     * already present. To contrast, alterAt() can reduce the size of the OrderedMap if replacement is already
2440     * in the Map. If replacement is found, this returns the default return value, otherwise it switches out the index
2441     * for replacement and returns whatever value was at the index before.
2442     * @param index       an index to replace the K key at
2443     * @param replacement another K key that will replace the original at the remembered index
2444     * @return the value associated with the key at the altered index before, and replacement now
2445     */
2446    public V alterAtCarefully(int index, K replacement)
2447    {
2448        return alterCarefully(keyAt(index), replacement);
2449    }
2450
2451    /**
2452     * If the specified key is not already associated with a value (or is mapped
2453     * to {@code null}) associates it with the given value and returns
2454     * {@code null}, else returns the current value.
2455     *
2456     * @param key   key with which the specified value is to be associated
2457     * @param value value to be associated with the specified key
2458     * @return the previous value associated with the specified key, or
2459     * {@code null} if there was no mapping for the key.
2460     * (A {@code null} return can also indicate that the map
2461     * previously associated {@code null} with the key.)
2462     */
2463    public V putIfAbsent(K key, V value) {
2464        V v = get(key);
2465        if(v == null)
2466            v = put(key, value);
2467        return v;
2468    }
2469
2470    /**
2471     * Removes the entry for the specified key only if it is currently
2472     * mapped to the specified value.
2473     *
2474     * @param key   key with which the specified value is associated
2475     * @param value value expected to be associated with the specified key
2476     * @return {@code true} if the value was removed
2477     */
2478    public boolean remove(Object key, Object value) {
2479        if (containsKey(key) && Objects.equals(get(key), value)) {
2480            remove(key);
2481            return true;
2482        } else
2483            return false;
2484    }
2485
2486    /**
2487     * Replaces the entry for the specified key only if currently
2488     * mapped to the specified value. The position in the iteration
2489     * order is retained.
2490     *
2491     * @param key      key with which the specified value is associated
2492     * @param oldValue value expected to be associated with the specified key
2493     * @param newValue value to be associated with the specified key
2494     * @return {@code true} if the value was replaced
2495     */
2496    public boolean replace(K key, V oldValue, V newValue) {
2497        if (containsKey(key)) {
2498            V v = get(key);
2499            if (v == oldValue || (oldValue != null && oldValue.equals(v))) {
2500                put(key, newValue);
2501                return true;
2502            }
2503        }
2504        return false;
2505    }
2506
2507    /**
2508     * Replaces the entry for the specified key only if it is
2509     * currently mapped to some value. Preserves the existing key's
2510     * position in the iteration order.
2511     *
2512     * @param key   key with which the specified value is associated
2513     * @param value value to be associated with the specified key
2514     * @return the previous value associated with the specified key, or
2515     * {@code null} if there was no mapping for the key.
2516     * (A {@code null} return can also indicate that the map
2517     * previously associated {@code null} with the key.)
2518     */
2519    public V replace(K key, V value) {
2520        if (containsKey(key)) {
2521            return put(key, value);
2522        } else
2523            return null;
2524    }
2525    /**
2526     * Given alternating key and value arguments in pairs, puts each key-value pair into this OrderedMap as if by
2527     * calling {@link #put(Object, Object)} repeatedly for each pair. This mimics the parameter syntax used for
2528     * {@link #makeMap(Object, Object, Object...)}, and can be used to retain that style of insertion after an
2529     * OrderedMap has been instantiated.
2530     * @param k0 the first key to add
2531     * @param v0 the first value to add
2532     * @param rest an array or vararg of keys and values in pairs; should contain alternating K, V, K, V... elements
2533     * @return this, after adding all viable key-value pairs given
2534     */
2535    @SuppressWarnings("unchecked")
2536    public OrderedMap<K, V> putPairs(K k0, V v0, Object... rest)
2537    {
2538        if(rest == null || rest.length == 0)
2539        {
2540            put(k0, v0);
2541            return this;
2542        }
2543        put(k0, v0);
2544
2545        for (int i = 0; i < rest.length - 1; i+=2) {
2546            try {
2547                put((K) rest[i], (V) rest[i + 1]);
2548            }catch (ClassCastException ignored) {
2549            }
2550        }
2551        return this;
2552    }
2553
2554    /**
2555     * Makes an OrderedMap (OM) with the given load factor (which should be between 0.1 and 0.9), key and value types
2556     * inferred from the types of k0 and v0, and considers all remaining parameters key-value pairs, casting the Objects
2557     * at positions 0, 2, 4... etc. to K and the objects at positions 1, 3, 5... etc. to V. If rest has an odd-number
2558     * length, then it discards the last item. If any pair of items in rest cannot be cast to the correct type of K or
2559     * V, then this inserts nothing for that pair. This is similar to the makeOM method in the Maker class, but does not
2560     * allow setting the load factor (since that extra parameter can muddle how javac figures out which generic types
2561     * the map should use), nor does it log debug information if a cast fails. The result should be the same otherwise.
2562     * <br>
2563     * This is named makeMap to indicate that it expects key and value parameters, unlike a Set or List. This convention
2564     * may be extended to other data structures that also have static methods for instantiation.
2565     * @param k0 the first key; used to infer the types of other keys if generic parameters aren't specified.
2566     * @param v0 the first value; used to infer the types of other values if generic parameters aren't specified.
2567     * @param rest an array or vararg of keys and values in pairs; should contain alternating K, V, K, V... elements
2568     * @param <K> the type of keys in the returned OrderedMap; if not specified, will be inferred from k0
2569     * @param <V> the type of values in the returned OrderedMap; if not specified, will be inferred from v0
2570     * @return a freshly-made OrderedMap with K keys and V values, using k0, v0, and the contents of rest to fill it
2571     */
2572    @SuppressWarnings("unchecked")
2573    public static <K, V> OrderedMap<K, V> makeMap(K k0, V v0, Object... rest)
2574    {
2575        if(rest == null || rest.length == 0)
2576        {
2577            OrderedMap<K, V> om = new OrderedMap<>(2);
2578            om.put(k0, v0);
2579            return om;
2580        }
2581        OrderedMap<K, V> om = new OrderedMap<>(1 + (rest.length >> 1));
2582        om.put(k0, v0);
2583
2584        for (int i = 0; i < rest.length - 1; i+=2) {
2585            try {
2586                om.put((K) rest[i], (V) rest[i + 1]);
2587            }catch (ClassCastException ignored) {
2588            }
2589        }
2590        return om;
2591    }
2592
2593    /**
2594     * Makes an empty OrderedMap (OM); needs key and value types to be specified in order to work. For an empty
2595     * OrderedMap with String keys and Coord values, you could use {@code Maker.<String, Coord>makeOM()}. Using
2596     * the new keyword is probably just as easy in this case; this method is provided for completeness relative to
2597     * makeMap() with 2 or more parameters.
2598     * @param <K> the type of keys in the returned OrderedMap; cannot be inferred and must be specified
2599     * @param <V> the type of values in the returned OrderedMap; cannot be inferred and must be specified
2600     * @return an empty OrderedMap with the given key and value types.
2601     */
2602    public static <K, V> OrderedMap<K, V> makeMap()
2603    {
2604        return new OrderedMap<>();
2605    }
2606
2607
2608    /**
2609     * Sorts this whole OrderedMap on its keys using the supplied Comparator.
2610     * @param comparator a Comparator that can be used on the same type this uses for its keys (may need wildcards)
2611     */
2612    public void sort(Comparator<? super K> comparator)
2613    {
2614        sort(comparator, 0, size);
2615    }
2616
2617    /**
2618     * Sorts a sub-range of this OrderedMap on its keys from what is currently the index {@code start} up to (but not
2619     * including) the index {@code end}, using the supplied Comparator.
2620     * @param comparator a Comparator that can be used on the same type this uses for its keys (may need wildcards)
2621     * @param start the first index of a key to sort (the index can change after this)
2622     * @param end the exclusive bound on the indices to sort; often this is just {@link #size()}
2623     */
2624    public void sort(Comparator<? super K> comparator, int start, int end)
2625    {
2626        TimSort.sort(key, order, start, end, comparator);
2627    }
2628    /**
2629     * Sorts this whole OrderedMap on its values using the supplied Comparator.
2630     * @param comparator a Comparator that can be used on the same type this uses for its values (may need wildcards)
2631     */
2632    public void sortByValue(Comparator<? super V> comparator)
2633    {
2634        sortByValue(comparator, 0, size);
2635    }
2636
2637    /**
2638     * Sorts a sub-range of this OrderedMap on its values from what is currently the index {@code start} up to (but not
2639     * including) the index {@code end}, using the supplied Comparator.
2640     * @param comparator a Comparator that can be used on the same type this uses for its values (may need wildcards)
2641     * @param start the first index of a value to sort (the index can change after this)
2642     * @param end the exclusive bound on the indices to sort; often this is just {@link #size()}
2643     */
2644    public void sortByValue(Comparator<? super V> comparator, int start, int end)
2645    {
2646        TimSort.sort(value, order, start, end, comparator);
2647    }
2648
2649    /**
2650     * Reverses the iteration order in linear time.
2651     */
2652    public void reverse()
2653    {
2654        order.reverse();
2655    }
2656}