AbstractHashedMap.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.map;

  18. import java.io.IOException;
  19. import java.io.ObjectInputStream;
  20. import java.io.ObjectOutputStream;
  21. import java.util.AbstractCollection;
  22. import java.util.AbstractMap;
  23. import java.util.AbstractSet;
  24. import java.util.Arrays;
  25. import java.util.Collection;
  26. import java.util.ConcurrentModificationException;
  27. import java.util.Iterator;
  28. import java.util.Map;
  29. import java.util.NoSuchElementException;
  30. import java.util.Objects;
  31. import java.util.Set;

  32. import org.apache.commons.collections4.CollectionUtils;
  33. import org.apache.commons.collections4.IterableMap;
  34. import org.apache.commons.collections4.KeyValue;
  35. import org.apache.commons.collections4.MapIterator;
  36. import org.apache.commons.collections4.iterators.EmptyIterator;
  37. import org.apache.commons.collections4.iterators.EmptyMapIterator;

  38. /**
  39.  * An abstract implementation of a hash-based map which provides numerous points for
  40.  * subclasses to override.
  41.  * <p>
  42.  * This class implements all the features necessary for a subclass hash-based map.
  43.  * Key-value entries are stored in instances of the {@code HashEntry} class,
  44.  * which can be overridden and replaced. The iterators can similarly be replaced,
  45.  * without the need to replace the KeySet, EntrySet and Values view classes.
  46.  * </p>
  47.  * <p>
  48.  * Overridable methods are provided to change the default hashing behavior, and
  49.  * to change how entries are added to and removed from the map. Hopefully, all you
  50.  * need for unusual subclasses is here.
  51.  * </p>
  52.  * <p>
  53.  * NOTE: From Commons Collections 3.1 this class extends AbstractMap.
  54.  * This is to provide backwards compatibility for ReferenceMap between v3.0 and v3.1.
  55.  * This extends clause will be removed in v5.0.
  56.  * </p>
  57.  *
  58.  * @param <K> the type of the keys in this map
  59.  * @param <V> the type of the values in this map
  60.  * @since 3.0
  61.  */
  62. public class AbstractHashedMap<K, V> extends AbstractMap<K, V> implements IterableMap<K, V> {

  63.     /**
  64.      * EntrySet implementation.
  65.      *
  66.      * @param <K> the type of the keys in the map
  67.      * @param <V> the type of the values in the map
  68.      */
  69.     protected static class EntrySet<K, V> extends AbstractSet<Map.Entry<K, V>> {

  70.         /** The parent map */
  71.         private final AbstractHashedMap<K, V> parent;

  72.         /**
  73.          * Constructs a new instance.
  74.          *
  75.          * @param parent The parent map.
  76.          */
  77.         protected EntrySet(final AbstractHashedMap<K, V> parent) {
  78.             this.parent = parent;
  79.         }

  80.         @Override
  81.         public void clear() {
  82.             parent.clear();
  83.         }

  84.         @Override
  85.         public boolean contains(final Object entry) {
  86.             if (entry instanceof Map.Entry) {
  87.                 final Map.Entry<?, ?> e = (Map.Entry<?, ?>) entry;
  88.                 final Entry<K, V> match = parent.getEntry(e.getKey());
  89.                 return match != null && match.equals(e);
  90.             }
  91.             return false;
  92.         }

  93.         @Override
  94.         public Iterator<Map.Entry<K, V>> iterator() {
  95.             return parent.createEntrySetIterator();
  96.         }

  97.         @Override
  98.         public boolean remove(final Object obj) {
  99.             if (!(obj instanceof Map.Entry)) {
  100.                 return false;
  101.             }
  102.             if (!contains(obj)) {
  103.                 return false;
  104.             }
  105.             final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
  106.             parent.remove(entry.getKey());
  107.             return true;
  108.         }

  109.         @Override
  110.         public int size() {
  111.             return parent.size();
  112.         }
  113.     }

  114.     /**
  115.      * EntrySet iterator.
  116.      *
  117.      * @param <K> the type of the keys in the map
  118.      * @param <V> the type of the values in the map
  119.      */
  120.     protected static class EntrySetIterator<K, V> extends HashIterator<K, V> implements Iterator<Map.Entry<K, V>> {

  121.         /**
  122.          * Constructs a new instance.
  123.          *
  124.          * @param parent The parent map.
  125.          */
  126.         protected EntrySetIterator(final AbstractHashedMap<K, V> parent) {
  127.             super(parent);
  128.         }

  129.         @Override
  130.         public Map.Entry<K, V> next() {
  131.             return super.nextEntry();
  132.         }
  133.     }

  134.     /**
  135.      * HashEntry used to store the data.
  136.      * <p>
  137.      * If you subclass {@code AbstractHashedMap} but not {@code HashEntry}
  138.      * then you will not be able to access the protected fields.
  139.      * The {@code entryXxx()} methods on {@code AbstractHashedMap} exist
  140.      * to provide the necessary access.
  141.      * </p>
  142.      *
  143.      * @param <K> the type of the keys
  144.      * @param <V> the type of the values
  145.      */
  146.     protected static class HashEntry<K, V> implements Map.Entry<K, V>, KeyValue<K, V> {

  147.         /** The next entry in the hash chain */
  148.         protected HashEntry<K, V> next;

  149.         /** The hash code of the key */
  150.         protected int hashCode;

  151.         /** The key */
  152.         protected Object key;

  153.         /** The value */
  154.         protected Object value;

  155.         /**
  156.          * Constructs a new instance.
  157.          *
  158.          * @param next next.
  159.          * @param hashCode hash code.
  160.          * @param key key.
  161.          * @param value value.
  162.          */
  163.         protected HashEntry(final HashEntry<K, V> next, final int hashCode, final Object key, final V value) {
  164.             this.next = next;
  165.             this.hashCode = hashCode;
  166.             this.key = key;
  167.             this.value = value;
  168.         }

  169.         @Override
  170.         public boolean equals(final Object obj) {
  171.             if (obj == this) {
  172.                 return true;
  173.             }
  174.             if (!(obj instanceof Map.Entry)) {
  175.                 return false;
  176.             }
  177.             final Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
  178.             return
  179.                 Objects.equals(getKey(), other.getKey()) &&
  180.                 Objects.equals(getValue(), other.getValue());
  181.         }

  182.         @Override
  183.         @SuppressWarnings("unchecked")
  184.         public K getKey() {
  185.             if (key == NULL) {
  186.                 return null;
  187.             }
  188.             return (K) key;
  189.         }

  190.         @Override
  191.         @SuppressWarnings("unchecked")
  192.         public V getValue() {
  193.             return (V) value;
  194.         }

  195.         @Override
  196.         public int hashCode() {
  197.             return (getKey() == null ? 0 : getKey().hashCode()) ^
  198.                    (getValue() == null ? 0 : getValue().hashCode());
  199.         }

  200.         @Override
  201.         @SuppressWarnings("unchecked")
  202.         public V setValue(final V value) {
  203.             final Object old = this.value;
  204.             this.value = value;
  205.             return (V) old;
  206.         }

  207.         @Override
  208.         public String toString() {
  209.             return new StringBuilder().append(getKey()).append('=').append(getValue()).toString();
  210.         }
  211.     }
  212.     /**
  213.      * Base Iterator.
  214.      *
  215.      * @param <K> the type of the keys in the map
  216.      * @param <V> the type of the values in the map
  217.      */
  218.     protected abstract static class HashIterator<K, V> {

  219.         /** The parent map */
  220.         private final AbstractHashedMap<K, V> parent;

  221.         /** The current index into the array of buckets */
  222.         private int hashIndex;

  223.         /** The last returned entry */
  224.         private HashEntry<K, V> last;

  225.         /** The next entry */
  226.         private HashEntry<K, V> next;

  227.         /** The modification count expected */
  228.         private int expectedModCount;

  229.         /**
  230.          * Constructs a new instance.
  231.          *
  232.          * @param parent The parent AbstractHashedMap.
  233.          */
  234.         protected HashIterator(final AbstractHashedMap<K, V> parent) {
  235.             this.parent = parent;
  236.             final HashEntry<K, V>[] data = parent.data;
  237.             int i = data.length;
  238.             HashEntry<K, V> next = null;
  239.             while (i > 0 && next == null) {
  240.                 next = data[--i];
  241.             }
  242.             this.next = next;
  243.             this.hashIndex = i;
  244.             this.expectedModCount = parent.modCount;
  245.         }

  246.         /**
  247.          * Gets the current entry.
  248.          *
  249.          * @return the current entry.
  250.          */
  251.         protected HashEntry<K, V> currentEntry() {
  252.             return last;
  253.         }

  254.         /**
  255.          * Tests whether there is a next entry.
  256.          *
  257.          * @return whether there is a next entry.
  258.          */
  259.         public boolean hasNext() {
  260.             return next != null;
  261.         }

  262.         /**
  263.          * Gets the next entry.
  264.          *
  265.          * @return the next entry.
  266.          */
  267.         protected HashEntry<K, V> nextEntry() {
  268.             if (parent.modCount != expectedModCount) {
  269.                 throw new ConcurrentModificationException();
  270.             }
  271.             final HashEntry<K, V> newCurrent = next;
  272.             if (newCurrent == null)  {
  273.                 throw new NoSuchElementException(NO_NEXT_ENTRY);
  274.             }
  275.             final HashEntry<K, V>[] data = parent.data;
  276.             int i = hashIndex;
  277.             HashEntry<K, V> n = newCurrent.next;
  278.             while (n == null && i > 0) {
  279.                 n = data[--i];
  280.             }
  281.             next = n;
  282.             hashIndex = i;
  283.             last = newCurrent;
  284.             return newCurrent;
  285.         }

  286.         /**
  287.          * Removes the current element.
  288.          */
  289.         public void remove() {
  290.             if (last == null) {
  291.                 throw new IllegalStateException(REMOVE_INVALID);
  292.             }
  293.             if (parent.modCount != expectedModCount) {
  294.                 throw new ConcurrentModificationException();
  295.             }
  296.             parent.remove(last.getKey());
  297.             last = null;
  298.             expectedModCount = parent.modCount;
  299.         }

  300.         @Override
  301.         public String toString() {
  302.             if (last != null) {
  303.                 return "Iterator[" + last.getKey() + "=" + last.getValue() + "]";
  304.             }
  305.             return "Iterator[]";
  306.         }
  307.     }

  308.     /**
  309.      * MapIterator implementation.
  310.      *
  311.      * @param <K> the type of the keys in the map
  312.      * @param <V> the type of the values in the map
  313.      */
  314.     protected static class HashMapIterator<K, V> extends HashIterator<K, V> implements MapIterator<K, V> {

  315.         /**
  316.          * Constructs a new instance.
  317.          *
  318.          * @param parent The parent AbstractHashedMap.
  319.          */
  320.         protected HashMapIterator(final AbstractHashedMap<K, V> parent) {
  321.             super(parent);
  322.         }

  323.         @Override
  324.         public K getKey() {
  325.             final HashEntry<K, V> current = currentEntry();
  326.             if (current == null) {
  327.                 throw new IllegalStateException(GETKEY_INVALID);
  328.             }
  329.             return current.getKey();
  330.         }

  331.         @Override
  332.         public V getValue() {
  333.             final HashEntry<K, V> current = currentEntry();
  334.             if (current == null) {
  335.                 throw new IllegalStateException(GETVALUE_INVALID);
  336.             }
  337.             return current.getValue();
  338.         }

  339.         @Override
  340.         public K next() {
  341.             return super.nextEntry().getKey();
  342.         }

  343.         @Override
  344.         public V setValue(final V value) {
  345.             final HashEntry<K, V> current = currentEntry();
  346.             if (current == null) {
  347.                 throw new IllegalStateException(SETVALUE_INVALID);
  348.             }
  349.             return current.setValue(value);
  350.         }
  351.     }

  352.     /**
  353.      * KeySet implementation.
  354.      *
  355.      * @param <K> the type of elements maintained by this set
  356.      */
  357.     protected static class KeySet<K> extends AbstractSet<K> {

  358.         /** The parent map */
  359.         private final AbstractHashedMap<K, ?> parent;

  360.         /**
  361.          * Constructs a new instance.
  362.          *
  363.          * @param parent The parent AbstractHashedMap.
  364.          */
  365.         protected KeySet(final AbstractHashedMap<K, ?> parent) {
  366.             this.parent = parent;
  367.         }

  368.         @Override
  369.         public void clear() {
  370.             parent.clear();
  371.         }

  372.         @Override
  373.         public boolean contains(final Object key) {
  374.             return parent.containsKey(key);
  375.         }

  376.         @Override
  377.         public Iterator<K> iterator() {
  378.             return parent.createKeySetIterator();
  379.         }

  380.         @Override
  381.         public boolean remove(final Object key) {
  382.             final boolean result = parent.containsKey(key);
  383.             parent.remove(key);
  384.             return result;
  385.         }

  386.         @Override
  387.         public int size() {
  388.             return parent.size();
  389.         }
  390.     }

  391.     /**
  392.      * KeySet iterator.
  393.      *
  394.      * @param <K> the type of elements maintained by this set
  395.      */
  396.     protected static class KeySetIterator<K> extends HashIterator<K, Object> implements Iterator<K> {

  397.         /**
  398.          * Constructs a new instance.
  399.          *
  400.          * @param parent The parent AbstractHashedMap.
  401.          */
  402.         @SuppressWarnings("unchecked")
  403.         protected KeySetIterator(final AbstractHashedMap<K, ?> parent) {
  404.             super((AbstractHashedMap<K, Object>) parent);
  405.         }

  406.         @Override
  407.         public K next() {
  408.             return super.nextEntry().getKey();
  409.         }
  410.     }

  411.     /**
  412.      * Values implementation.
  413.      *
  414.      * @param <V> the type of elements maintained by this collection
  415.      */
  416.     protected static class Values<V> extends AbstractCollection<V> {

  417.         /** The parent map */
  418.         private final AbstractHashedMap<?, V> parent;

  419.         /**
  420.          * Constructs a new instance.
  421.          *
  422.          * @param parent The parent AbstractHashedMap.
  423.          */
  424.         protected Values(final AbstractHashedMap<?, V> parent) {
  425.             this.parent = parent;
  426.         }

  427.         @Override
  428.         public void clear() {
  429.             parent.clear();
  430.         }

  431.         @Override
  432.         public boolean contains(final Object value) {
  433.             return parent.containsValue(value);
  434.         }

  435.         @Override
  436.         public Iterator<V> iterator() {
  437.             return parent.createValuesIterator();
  438.         }

  439.         @Override
  440.         public int size() {
  441.             return parent.size();
  442.         }
  443.     }

  444.     /**
  445.      * Values iterator.
  446.      *
  447.      * @param <V> the type of elements maintained by this collection
  448.      */
  449.     protected static class ValuesIterator<V> extends HashIterator<Object, V> implements Iterator<V> {

  450.         /**
  451.          * Constructs a new instance.
  452.          *
  453.          * @param parent The parent AbstractHashedMap.
  454.          */
  455.         @SuppressWarnings("unchecked")
  456.         protected ValuesIterator(final AbstractHashedMap<?, V> parent) {
  457.             super((AbstractHashedMap<Object, V>) parent);
  458.         }

  459.         @Override
  460.         public V next() {
  461.             return super.nextEntry().getValue();
  462.         }
  463.     }

  464.     /** Exception message. */
  465.     protected static final String NO_NEXT_ENTRY = "No next() entry in the iteration";

  466.     /** Exception message. */
  467.     protected static final String NO_PREVIOUS_ENTRY = "No previous() entry in the iteration";

  468.     /** Exception message. */
  469.     protected static final String REMOVE_INVALID = "remove() can only be called once after next()";

  470.     /** Exception message. */
  471.     protected static final String GETKEY_INVALID = "getKey() can only be called after next() and before remove()";

  472.     /** Exception message. */
  473.     protected static final String GETVALUE_INVALID = "getValue() can only be called after next() and before remove()";

  474.     /** Exception message. */
  475.     protected static final String SETVALUE_INVALID = "setValue() can only be called after next() and before remove()";

  476.     /** The default capacity to use */
  477.     protected static final int DEFAULT_CAPACITY = 16;

  478.     /** The default threshold to use */
  479.     protected static final int DEFAULT_THRESHOLD = 12;

  480.     /** The default load factor to use */
  481.     protected static final float DEFAULT_LOAD_FACTOR = 0.75f;

  482.     /** The maximum capacity allowed */
  483.     protected static final int MAXIMUM_CAPACITY = 1 << 30;

  484.     /** An object for masking null */
  485.     protected static final Object NULL = new Object();

  486.     /** Load factor, normally 0.75 */
  487.     transient float loadFactor;

  488.     /** The size of the map */
  489.     transient int size;

  490.     /** Map entries */
  491.     transient HashEntry<K, V>[] data;

  492.     /** Size at which to rehash */
  493.     transient int threshold;

  494.     /** Modification count for iterators */
  495.     transient int modCount;

  496.     /** Entry set */
  497.     transient EntrySet<K, V> entrySet;

  498.     /** Key set */
  499.     transient KeySet<K> keySet;

  500.     /** Values */
  501.     transient Values<V> values;

  502.     /**
  503.      * Constructor only used in deserialization, do not use otherwise.
  504.      */
  505.     protected AbstractHashedMap() {
  506.     }

  507.     /**
  508.      * Constructs a new, empty map with the specified initial capacity and
  509.      * default load factor.
  510.      *
  511.      * @param initialCapacity  the initial capacity
  512.      * @throws IllegalArgumentException if the initial capacity is negative
  513.      */
  514.     protected AbstractHashedMap(final int initialCapacity) {
  515.         this(initialCapacity, DEFAULT_LOAD_FACTOR);
  516.     }

  517.     /**
  518.      * Constructs a new, empty map with the specified initial capacity and
  519.      * load factor.
  520.      *
  521.      * @param initialCapacity  the initial capacity
  522.      * @param loadFactor  the load factor
  523.      * @throws IllegalArgumentException if the initial capacity is negative
  524.      * @throws IllegalArgumentException if the load factor is less than or equal to zero
  525.      */
  526.     @SuppressWarnings("unchecked")
  527.     protected AbstractHashedMap(int initialCapacity, final float loadFactor) {
  528.         if (initialCapacity < 0) {
  529.             throw new IllegalArgumentException("Initial capacity must be a non negative number");
  530.         }
  531.         if (loadFactor <= 0.0f || Float.isNaN(loadFactor)) {
  532.             throw new IllegalArgumentException("Load factor must be greater than 0");
  533.         }
  534.         this.loadFactor = loadFactor;
  535.         initialCapacity = calculateNewCapacity(initialCapacity);
  536.         this.threshold = calculateThreshold(initialCapacity, loadFactor);
  537.         this.data = new HashEntry[initialCapacity];
  538.         init();
  539.     }

  540.     /**
  541.      * Constructor which performs no validation on the passed in parameters.
  542.      *
  543.      * @param initialCapacity  the initial capacity, must be a power of two
  544.      * @param loadFactor  the load factor, must be &gt; 0.0f and generally &lt; 1.0f
  545.      * @param threshold  the threshold, must be sensible
  546.      */
  547.     @SuppressWarnings("unchecked")
  548.     protected AbstractHashedMap(final int initialCapacity, final float loadFactor, final int threshold) {
  549.         this.loadFactor = loadFactor;
  550.         this.data = new HashEntry[initialCapacity];
  551.         this.threshold = threshold;
  552.         init();
  553.     }

  554.     /**
  555.      * Constructor copying elements from another map.
  556.      *
  557.      * @param map  the map to copy
  558.      * @throws NullPointerException if the map is null
  559.      */
  560.     protected AbstractHashedMap(final Map<? extends K, ? extends V> map) {
  561.         this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
  562.         putAll(map);
  563.     }

  564.     /**
  565.      * Adds an entry into this map.
  566.      * <p>
  567.      * This implementation adds the entry to the data storage table.
  568.      * Subclasses could override to handle changes to the map.
  569.      * </p>
  570.      *
  571.      * @param entry  the entry to add
  572.      * @param hashIndex  the index into the data array to store at
  573.      */
  574.     protected void addEntry(final HashEntry<K, V> entry, final int hashIndex) {
  575.         data[hashIndex] = entry;
  576.     }

  577.     /**
  578.      * Adds a new key-value mapping into this map.
  579.      * <p>
  580.      * This implementation calls {@code createEntry()}, {@code addEntry()}
  581.      * and {@code checkCapacity()}.
  582.      * It also handles changes to {@code modCount} and {@code size}.
  583.      * Subclasses could override to fully control adds to the map.
  584.      * </p>
  585.      *
  586.      * @param hashIndex  the index into the data array to store at
  587.      * @param hashCode  the hash code of the key to add
  588.      * @param key  the key to add
  589.      * @param value  the value to add
  590.      */
  591.     protected void addMapping(final int hashIndex, final int hashCode, final K key, final V value) {
  592.         modCount++;
  593.         final HashEntry<K, V> entry = createEntry(data[hashIndex], hashCode, key, value);
  594.         addEntry(entry, hashIndex);
  595.         size++;
  596.         checkCapacity();
  597.     }

  598.     /**
  599.      * Calculates the new capacity of the map.
  600.      * This implementation normalizes the capacity to a power of two.
  601.      *
  602.      * @param proposedCapacity  the proposed capacity
  603.      * @return the normalized new capacity
  604.      */
  605.     protected int calculateNewCapacity(final int proposedCapacity) {
  606.         int newCapacity = 1;
  607.         if (proposedCapacity > MAXIMUM_CAPACITY) {
  608.             newCapacity = MAXIMUM_CAPACITY;
  609.         } else {
  610.             while (newCapacity < proposedCapacity) {
  611.                 newCapacity <<= 1;  // multiply by two
  612.             }
  613.             if (newCapacity > MAXIMUM_CAPACITY) {
  614.                 newCapacity = MAXIMUM_CAPACITY;
  615.             }
  616.         }
  617.         return newCapacity;
  618.     }

  619.     /**
  620.      * Calculates the new threshold of the map, where it will be resized.
  621.      * This implementation uses the load factor.
  622.      *
  623.      * @param newCapacity  the new capacity
  624.      * @param factor  the load factor
  625.      * @return the new resize threshold
  626.      */
  627.     protected int calculateThreshold(final int newCapacity, final float factor) {
  628.         return (int) (newCapacity * factor);
  629.     }

  630.     /**
  631.      * Checks the capacity of the map and enlarges it if necessary.
  632.      * <p>
  633.      * This implementation uses the threshold to check if the map needs enlarging
  634.      * </p>
  635.      */
  636.     protected void checkCapacity() {
  637.         if (size >= threshold) {
  638.             final int newCapacity = data.length * 2;
  639.             if (newCapacity <= MAXIMUM_CAPACITY) {
  640.                 ensureCapacity(newCapacity);
  641.             }
  642.         }
  643.     }

  644.     /**
  645.      * Clears the map, resetting the size to zero and nullifying references
  646.      * to avoid garbage collection issues.
  647.      */
  648.     @Override
  649.     public void clear() {
  650.         modCount++;
  651.         final HashEntry<K, V>[] data = this.data;
  652.         Arrays.fill(data, null);
  653.         size = 0;
  654.     }

  655.     /**
  656.      * Clones the map without cloning the keys or values.
  657.      * <p>
  658.      * To implement {@code clone()}, a subclass must implement the
  659.      * {@code Cloneable} interface and make this method public.
  660.      * </p>
  661.      *
  662.      * @return a shallow clone
  663.      * @throws InternalError if {@link AbstractMap#clone()} failed
  664.      */
  665.     @Override
  666.     @SuppressWarnings("unchecked")
  667.     protected AbstractHashedMap<K, V> clone() {
  668.         try {
  669.             final AbstractHashedMap<K, V> cloned = (AbstractHashedMap<K, V>) super.clone();
  670.             cloned.data = new HashEntry[data.length];
  671.             cloned.entrySet = null;
  672.             cloned.keySet = null;
  673.             cloned.values = null;
  674.             cloned.modCount = 0;
  675.             cloned.size = 0;
  676.             cloned.init();
  677.             cloned.putAll(this);
  678.             return cloned;
  679.         } catch (final CloneNotSupportedException ex) {
  680.             throw new UnsupportedOperationException(ex);
  681.         }
  682.     }

  683.     /**
  684.      * Checks whether the map contains the specified key.
  685.      *
  686.      * @param key  the key to search for
  687.      * @return true if the map contains the key
  688.      */
  689.     @Override
  690.     public boolean containsKey(Object key) {
  691.         key = convertKey(key);
  692.         final int hashCode = hash(key);
  693.         HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
  694.         while (entry != null) {
  695.             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
  696.                 return true;
  697.             }
  698.             entry = entry.next;
  699.         }
  700.         return false;
  701.     }

  702.     /**
  703.      * Checks whether the map contains the specified value.
  704.      *
  705.      * @param value  the value to search for
  706.      * @return true if the map contains the value
  707.      */
  708.     @Override
  709.     public boolean containsValue(final Object value) {
  710.         if (value == null) {
  711.             for (final HashEntry<K, V> element : data) {
  712.                 HashEntry<K, V> entry = element;
  713.                 while (entry != null) {
  714.                     if (entry.getValue() == null) {
  715.                         return true;
  716.                     }
  717.                     entry = entry.next;
  718.                 }
  719.             }
  720.         } else {
  721.             for (final HashEntry<K, V> element : data) {
  722.                 HashEntry<K, V> entry = element;
  723.                 while (entry != null) {
  724.                     if (isEqualValue(value, entry.getValue())) {
  725.                         return true;
  726.                     }
  727.                     entry = entry.next;
  728.                 }
  729.             }
  730.         }
  731.         return false;
  732.     }

  733.     /**
  734.      * Converts input keys to another object for storage in the map.
  735.      * This implementation masks nulls.
  736.      * Subclasses can override this to perform alternate key conversions.
  737.      * <p>
  738.      * The reverse conversion can be changed, if required, by overriding the
  739.      * getKey() method in the hash entry.
  740.      * </p>
  741.      *
  742.      * @param key  the key convert
  743.      * @return the converted key
  744.      */
  745.     protected Object convertKey(final Object key) {
  746.         return key == null ? NULL : key;
  747.     }

  748.     /**
  749.      * Creates an entry to store the key-value data.
  750.      * <p>
  751.      * This implementation creates a new HashEntry instance.
  752.      * Subclasses can override this to return a different storage class,
  753.      * or implement caching.
  754.      * </p>
  755.      *
  756.      * @param next  the next entry in sequence
  757.      * @param hashCode  the hash code to use
  758.      * @param key  the key to store
  759.      * @param value  the value to store
  760.      * @return the newly created entry
  761.      */
  762.     protected HashEntry<K, V> createEntry(final HashEntry<K, V> next, final int hashCode, final K key, final V value) {
  763.         return new HashEntry<>(next, hashCode, convertKey(key), value);
  764.     }

  765.     /**
  766.      * Creates an entry set iterator.
  767.      * Subclasses can override this to return iterators with different properties.
  768.      *
  769.      * @return the entrySet iterator
  770.      */
  771.     protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
  772.         if (isEmpty()) {
  773.             return EmptyIterator.<Map.Entry<K, V>>emptyIterator();
  774.         }
  775.         return new EntrySetIterator<>(this);
  776.     }

  777.     /**
  778.      * Creates a key set iterator.
  779.      * Subclasses can override this to return iterators with different properties.
  780.      *
  781.      * @return the keySet iterator
  782.      */
  783.     protected Iterator<K> createKeySetIterator() {
  784.         if (isEmpty()) {
  785.             return EmptyIterator.<K>emptyIterator();
  786.         }
  787.         return new KeySetIterator<>(this);
  788.     }

  789.     /**
  790.      * Creates a values iterator.
  791.      * Subclasses can override this to return iterators with different properties.
  792.      *
  793.      * @return the values iterator
  794.      */
  795.     protected Iterator<V> createValuesIterator() {
  796.         if (isEmpty()) {
  797.             return EmptyIterator.<V>emptyIterator();
  798.         }
  799.         return new ValuesIterator<>(this);
  800.     }

  801.     /**
  802.      * Kills an entry ready for the garbage collector.
  803.      * <p>
  804.      * This implementation prepares the HashEntry for garbage collection.
  805.      * Subclasses can override this to implement caching (override clear as well).
  806.      * </p>
  807.      *
  808.      * @param entry  the entry to destroy
  809.      */
  810.     protected void destroyEntry(final HashEntry<K, V> entry) {
  811.         entry.next = null;
  812.         entry.key = null;
  813.         entry.value = null;
  814.     }

  815.     /**
  816.      * Reads the map data from the stream. This method must be overridden if a
  817.      * subclass must be setup before {@code put()} is used.
  818.      * <p>
  819.      * Serialization is not one of the JDK's nicest topics. Normal serialization will
  820.      * initialize the superclass before the subclass. Sometimes however, this isn't
  821.      * what you want, as in this case the {@code put()} method on read can be
  822.      * affected by subclass state.
  823.      * </p>
  824.      * <p>
  825.      * The solution adopted here is to deserialize the state data of this class in
  826.      * this protected method. This method must be called by the
  827.      * {@code readObject()} of the first serializable subclass.
  828.      * </p>
  829.      * <p>
  830.      * Subclasses may override if the subclass has a specific field that must be present
  831.      * before {@code put()} or {@code calculateThreshold()} will work correctly.
  832.      * </p>
  833.      *
  834.      * @param in  the input stream
  835.      * @throws IOException if an error occurs while reading from the stream
  836.      * @throws ClassNotFoundException if an object read from the stream cannot be loaded
  837.      */
  838.     @SuppressWarnings("unchecked")
  839.     protected void doReadObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
  840.         loadFactor = in.readFloat();
  841.         final int capacity = in.readInt();
  842.         final int size = in.readInt();
  843.         init();
  844.         threshold = calculateThreshold(capacity, loadFactor);
  845.         data = new HashEntry[capacity];
  846.         for (int i = 0; i < size; i++) {
  847.             final K key = (K) in.readObject();
  848.             final V value = (V) in.readObject();
  849.             put(key, value);
  850.         }
  851.     }

  852.     /**
  853.      * Writes the map data to the stream. This method must be overridden if a
  854.      * subclass must be setup before {@code put()} is used.
  855.      * <p>
  856.      * Serialization is not one of the JDK's nicest topics. Normal serialization will
  857.      * initialize the superclass before the subclass. Sometimes however, this isn't
  858.      * what you want, as in this case the {@code put()} method on read can be
  859.      * affected by subclass state.
  860.      * </p>
  861.      * <p>
  862.      * The solution adopted here is to serialize the state data of this class in
  863.      * this protected method. This method must be called by the
  864.      * {@code writeObject()} of the first serializable subclass.
  865.      * </p>
  866.      * <p>
  867.      * Subclasses may override if they have a specific field that must be present
  868.      * on read before this implementation will work. Generally, the read determines
  869.      * what must be serialized here, if anything.
  870.      * </p>
  871.      *
  872.      * @param out  the output stream
  873.      * @throws IOException if an error occurs while writing to the stream
  874.      */
  875.     protected void doWriteObject(final ObjectOutputStream out) throws IOException {
  876.         out.writeFloat(loadFactor);
  877.         out.writeInt(data.length);
  878.         out.writeInt(size);
  879.         for (final MapIterator<K, V> it = mapIterator(); it.hasNext();) {
  880.             out.writeObject(it.next());
  881.             out.writeObject(it.getValue());
  882.         }
  883.     }

  884.     /**
  885.      * Changes the size of the data structure to the capacity proposed.
  886.      *
  887.      * @param newCapacity  the new capacity of the array (a power of two, less or equal to max)
  888.      */
  889.     @SuppressWarnings("unchecked")
  890.     protected void ensureCapacity(final int newCapacity) {
  891.         final int oldCapacity = data.length;
  892.         if (newCapacity <= oldCapacity) {
  893.             return;
  894.         }
  895.         if (size == 0) {
  896.             threshold = calculateThreshold(newCapacity, loadFactor);
  897.             data = new HashEntry[newCapacity];
  898.         } else {
  899.             final HashEntry<K, V>[] oldEntries = data;
  900.             final HashEntry<K, V>[] newEntries = new HashEntry[newCapacity];

  901.             modCount++;
  902.             for (int i = oldCapacity - 1; i >= 0; i--) {
  903.                 HashEntry<K, V> entry = oldEntries[i];
  904.                 if (entry != null) {
  905.                     oldEntries[i] = null;  // gc
  906.                     do {
  907.                         final HashEntry<K, V> next = entry.next;
  908.                         final int index = hashIndex(entry.hashCode, newCapacity);
  909.                         entry.next = newEntries[index];
  910.                         newEntries[index] = entry;
  911.                         entry = next;
  912.                     } while (entry != null);
  913.                 }
  914.             }
  915.             threshold = calculateThreshold(newCapacity, loadFactor);
  916.             data = newEntries;
  917.         }
  918.     }

  919.     /**
  920.      * Gets the {@code hashCode} field from a {@code HashEntry}.
  921.      * Used in subclasses that have no visibility of the field.
  922.      *
  923.      * @param entry  the entry to query, must not be null
  924.      * @return the {@code hashCode} field of the entry
  925.      * @throws NullPointerException if the entry is null
  926.      * @since 3.1
  927.      */
  928.     protected int entryHashCode(final HashEntry<K, V> entry) {
  929.         return entry.hashCode;
  930.     }

  931.     /**
  932.      * Gets the {@code key} field from a {@code HashEntry}.
  933.      * Used in subclasses that have no visibility of the field.
  934.      *
  935.      * @param entry  the entry to query, must not be null
  936.      * @return the {@code key} field of the entry
  937.      * @throws NullPointerException if the entry is null
  938.      * @since 3.1
  939.      */
  940.     protected K entryKey(final HashEntry<K, V> entry) {
  941.         return entry.getKey();
  942.     }

  943.     /**
  944.      * Gets the {@code next} field from a {@code HashEntry}.
  945.      * Used in subclasses that have no visibility of the field.
  946.      *
  947.      * @param entry  the entry to query, must not be null
  948.      * @return the {@code next} field of the entry
  949.      * @throws NullPointerException if the entry is null
  950.      * @since 3.1
  951.      */
  952.     protected HashEntry<K, V> entryNext(final HashEntry<K, V> entry) {
  953.         return entry.next;
  954.     }

  955.     /**
  956.      * Gets the entrySet view of the map.
  957.      * Changes made to the view affect this map.
  958.      * To simply iterate through the entries, use {@link #mapIterator()}.
  959.      *
  960.      * @return the entrySet view
  961.      */
  962.     @Override
  963.     public Set<Map.Entry<K, V>> entrySet() {
  964.         if (entrySet == null) {
  965.             entrySet = new EntrySet<>(this);
  966.         }
  967.         return entrySet;
  968.     }

  969.     /**
  970.      * Gets the {@code value} field from a {@code HashEntry}.
  971.      * Used in subclasses that have no visibility of the field.
  972.      *
  973.      * @param entry  the entry to query, must not be null
  974.      * @return the {@code value} field of the entry
  975.      * @throws NullPointerException if the entry is null
  976.      * @since 3.1
  977.      */
  978.     protected V entryValue(final HashEntry<K, V> entry) {
  979.         return entry.getValue();
  980.     }

  981.     /**
  982.      * Compares this map with another.
  983.      *
  984.      * @param obj  the object to compare to
  985.      * @return true if equal
  986.      */
  987.     @Override
  988.     public boolean equals(final Object obj) {
  989.         if (obj == this) {
  990.             return true;
  991.         }
  992.         if (!(obj instanceof Map)) {
  993.             return false;
  994.         }
  995.         final Map<?, ?> map = (Map<?, ?>) obj;
  996.         if (map.size() != size()) {
  997.             return false;
  998.         }
  999.         final MapIterator<?, ?> it = mapIterator();
  1000.         try {
  1001.             while (it.hasNext()) {
  1002.                 final Object key = it.next();
  1003.                 final Object value = it.getValue();
  1004.                 if (value == null) {
  1005.                     if (map.get(key) != null || !map.containsKey(key)) {
  1006.                         return false;
  1007.                     }
  1008.                 } else if (!value.equals(map.get(key))) {
  1009.                     return false;
  1010.                 }
  1011.             }
  1012.         } catch (final ClassCastException | NullPointerException ignored) {
  1013.             return false;
  1014.         }
  1015.         return true;
  1016.     }

  1017.     /**
  1018.      * Gets the value mapped to the key specified.
  1019.      *
  1020.      * @param key  the key
  1021.      * @return the mapped value, null if no match
  1022.      */
  1023.     @Override
  1024.     public V get(Object key) {
  1025.         key = convertKey(key);
  1026.         final int hashCode = hash(key);
  1027.         HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
  1028.         while (entry != null) {
  1029.             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
  1030.                 return entry.getValue();
  1031.             }
  1032.             entry = entry.next;
  1033.         }
  1034.         return null;
  1035.     }

  1036.     /**
  1037.      * Gets the entry mapped to the key specified.
  1038.      * <p>
  1039.      * This method exists for subclasses that may need to perform a multi-step
  1040.      * process accessing the entry. The public methods in this class don't use this
  1041.      * method to gain a small performance boost.
  1042.      * </p>
  1043.      *
  1044.      * @param key  the key
  1045.      * @return the entry, null if no match
  1046.      */
  1047.     protected HashEntry<K, V> getEntry(Object key) {
  1048.         key = convertKey(key);
  1049.         final int hashCode = hash(key);
  1050.         HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
  1051.         while (entry != null) {
  1052.             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
  1053.                 return entry;
  1054.             }
  1055.             entry = entry.next;
  1056.         }
  1057.         return null;
  1058.     }

  1059.     /**
  1060.      * Gets the hash code for the key specified.
  1061.      * This implementation uses the additional hashing routine from JDK1.4.
  1062.      * Subclasses can override this to return alternate hash codes.
  1063.      *
  1064.      * @param key  the key to get a hash code for
  1065.      * @return the hash code
  1066.      */
  1067.     protected int hash(final Object key) {
  1068.         // same as JDK 1.4
  1069.         int h = key.hashCode();
  1070.         h += ~(h << 9);
  1071.         h ^=  h >>> 14;
  1072.         h +=  h << 4;
  1073.         h ^=  h >>> 10;
  1074.         return h;
  1075.     }

  1076.     /**
  1077.      * Gets the standard Map hashCode.
  1078.      *
  1079.      * @return the hash code defined in the Map interface
  1080.      */
  1081.     @Override
  1082.     public int hashCode() {
  1083.         int total = 0;
  1084.         final Iterator<Map.Entry<K, V>> it = createEntrySetIterator();
  1085.         while (it.hasNext()) {
  1086.             total += it.next().hashCode();
  1087.         }
  1088.         return total;
  1089.     }

  1090.     /**
  1091.      * Gets the index into the data storage for the hashCode specified.
  1092.      * This implementation uses the least significant bits of the hashCode.
  1093.      * Subclasses can override this to return alternate bucketing.
  1094.      *
  1095.      * @param hashCode  the hash code to use
  1096.      * @param dataSize  the size of the data to pick a bucket from
  1097.      * @return the bucket index
  1098.      */
  1099.     protected int hashIndex(final int hashCode, final int dataSize) {
  1100.         return hashCode & dataSize - 1;
  1101.     }

  1102.     /**
  1103.      * Initialize subclasses during construction, cloning or deserialization.
  1104.      */
  1105.     protected void init() {
  1106.         // noop
  1107.     }

  1108.     /**
  1109.      * Checks whether the map is currently empty.
  1110.      *
  1111.      * @return true if the map is currently size zero
  1112.      */
  1113.     @Override
  1114.     public boolean isEmpty() {
  1115.         return size == 0;
  1116.     }

  1117.     /**
  1118.      * Compares two keys, in internal converted form, to see if they are equal.
  1119.      * This implementation uses the equals method and assumes neither key is null.
  1120.      * Subclasses can override this to match differently.
  1121.      *
  1122.      * @param key1  the first key to compare passed in from outside
  1123.      * @param key2  the second key extracted from the entry via {@code entry.key}
  1124.      * @return true if equal
  1125.      */
  1126.     protected boolean isEqualKey(final Object key1, final Object key2) {
  1127.         return Objects.equals(key1, key2);
  1128.     }

  1129.     /**
  1130.      * Compares two values, in external form, to see if they are equal.
  1131.      * This implementation uses the equals method and assumes neither value is null.
  1132.      * Subclasses can override this to match differently.
  1133.      *
  1134.      * @param value1  the first value to compare passed in from outside
  1135.      * @param value2  the second value extracted from the entry via {@code getValue()}
  1136.      * @return true if equal
  1137.      */
  1138.     protected boolean isEqualValue(final Object value1, final Object value2) {
  1139.         return Objects.equals(value1, value2);
  1140.     }

  1141.     /**
  1142.      * Gets the keySet view of the map.
  1143.      * Changes made to the view affect this map.
  1144.      * To simply iterate through the keys, use {@link #mapIterator()}.
  1145.      *
  1146.      * @return the keySet view
  1147.      */
  1148.     @Override
  1149.     public Set<K> keySet() {
  1150.         if (keySet == null) {
  1151.             keySet = new KeySet<>(this);
  1152.         }
  1153.         return keySet;
  1154.     }

  1155.     /**
  1156.      * Gets an iterator over the map.
  1157.      * Changes made to the iterator affect this map.
  1158.      * <p>
  1159.      * A MapIterator returns the keys in the map. It also provides convenient
  1160.      * methods to get the key and value, and set the value.
  1161.      * It avoids the need to create an entrySet/keySet/values object.
  1162.      * It also avoids creating the Map.Entry object.
  1163.      * </p>
  1164.      *
  1165.      * @return the map iterator
  1166.      */
  1167.     @Override
  1168.     public MapIterator<K, V> mapIterator() {
  1169.         if (size == 0) {
  1170.             return EmptyMapIterator.<K, V>emptyMapIterator();
  1171.         }
  1172.         return new HashMapIterator<>(this);
  1173.     }

  1174.     /**
  1175.      * Puts a key-value mapping into this map.
  1176.      *
  1177.      * @param key  the key to add
  1178.      * @param value  the value to add
  1179.      * @return the value previously mapped to this key, null if none
  1180.      */
  1181.     @Override
  1182.     public V put(final K key, final V value) {
  1183.         final Object convertedKey = convertKey(key);
  1184.         final int hashCode = hash(convertedKey);
  1185.         final int index = hashIndex(hashCode, data.length);
  1186.         HashEntry<K, V> entry = data[index];
  1187.         while (entry != null) {
  1188.             if (entry.hashCode == hashCode && isEqualKey(convertedKey, entry.key)) {
  1189.                 final V oldValue = entry.getValue();
  1190.                 updateEntry(entry, value);
  1191.                 return oldValue;
  1192.             }
  1193.             entry = entry.next;
  1194.         }

  1195.         addMapping(index, hashCode, key, value);
  1196.         return null;
  1197.     }

  1198.     /**
  1199.      * Puts all the values from the specified map into this map.
  1200.      * <p>
  1201.      * This implementation iterates around the specified map and
  1202.      * uses {@link #put(Object, Object)}.
  1203.      * </p>
  1204.      *
  1205.      * @param map  the map to add
  1206.      * @throws NullPointerException if the map is null
  1207.      */
  1208.     @Override
  1209.     public void putAll(final Map<? extends K, ? extends V> map) {
  1210.         final int mapSize = map.size();
  1211.         if (mapSize == 0) {
  1212.             return;
  1213.         }
  1214.         final int newSize = (int) ((size + mapSize) / loadFactor + 1);
  1215.         ensureCapacity(calculateNewCapacity(newSize));
  1216.         for (final Map.Entry<? extends K, ? extends V> entry: map.entrySet()) {
  1217.             put(entry.getKey(), entry.getValue());
  1218.         }
  1219.     }

  1220.     /**
  1221.      * Removes the specified mapping from this map.
  1222.      *
  1223.      * @param key  the mapping to remove
  1224.      * @return the value mapped to the removed key, null if key not in map
  1225.      */
  1226.     @Override
  1227.     public V remove(Object key) {
  1228.         key = convertKey(key);
  1229.         final int hashCode = hash(key);
  1230.         final int index = hashIndex(hashCode, data.length);
  1231.         HashEntry<K, V> entry = data[index];
  1232.         HashEntry<K, V> previous = null;
  1233.         while (entry != null) {
  1234.             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
  1235.                 final V oldValue = entry.getValue();
  1236.                 removeMapping(entry, index, previous);
  1237.                 return oldValue;
  1238.             }
  1239.             previous = entry;
  1240.             entry = entry.next;
  1241.         }
  1242.         return null;
  1243.     }

  1244.     /**
  1245.      * Removes an entry from the chain stored in a particular index.
  1246.      * <p>
  1247.      * This implementation removes the entry from the data storage table.
  1248.      * The size is not updated.
  1249.      * Subclasses could override to handle changes to the map.
  1250.      * </p>
  1251.      *
  1252.      * @param entry  the entry to remove
  1253.      * @param hashIndex  the index into the data structure
  1254.      * @param previous  the previous entry in the chain
  1255.      */
  1256.     protected void removeEntry(final HashEntry<K, V> entry, final int hashIndex, final HashEntry<K, V> previous) {
  1257.         if (previous == null) {
  1258.             data[hashIndex] = entry.next;
  1259.         } else {
  1260.             previous.next = entry.next;
  1261.         }
  1262.     }

  1263.     /**
  1264.      * Removes a mapping from the map.
  1265.      * <p>
  1266.      * This implementation calls {@code removeEntry()} and {@code destroyEntry()}.
  1267.      * It also handles changes to {@code modCount} and {@code size}.
  1268.      * Subclasses could override to fully control removals from the map.
  1269.      * </p>
  1270.      *
  1271.      * @param entry  the entry to remove
  1272.      * @param hashIndex  the index into the data structure
  1273.      * @param previous  the previous entry in the chain
  1274.      */
  1275.     protected void removeMapping(final HashEntry<K, V> entry, final int hashIndex, final HashEntry<K, V> previous) {
  1276.         modCount++;
  1277.         removeEntry(entry, hashIndex, previous);
  1278.         size--;
  1279.         destroyEntry(entry);
  1280.     }

  1281.     /**
  1282.      * Reuses an existing key-value mapping, storing completely new data.
  1283.      * <p>
  1284.      * This implementation sets all the data fields on the entry.
  1285.      * Subclasses could populate additional entry fields.
  1286.      * </p>
  1287.      *
  1288.      * @param entry  the entry to update, not null
  1289.      * @param hashIndex  the index in the data array
  1290.      * @param hashCode  the hash code of the key to add
  1291.      * @param key  the key to add
  1292.      * @param value  the value to add
  1293.      */
  1294.     protected void reuseEntry(final HashEntry<K, V> entry, final int hashIndex, final int hashCode,
  1295.                               final K key, final V value) {
  1296.         entry.next = data[hashIndex];
  1297.         entry.hashCode = hashCode;
  1298.         entry.key = key;
  1299.         entry.value = value;
  1300.     }

  1301.     /**
  1302.      * Gets the size of the map.
  1303.      *
  1304.      * @return the size
  1305.      */
  1306.     @Override
  1307.     public int size() {
  1308.         return size;
  1309.     }

  1310.     /**
  1311.      * Gets the map as a String.
  1312.      *
  1313.      * @return a string version of the map
  1314.      */
  1315.     @Override
  1316.     public String toString() {
  1317.         if (isEmpty()) {
  1318.             return "{}";
  1319.         }
  1320.         final StringBuilder buf = new StringBuilder(32 * size());
  1321.         buf.append('{');

  1322.         final MapIterator<K, V> it = mapIterator();
  1323.         boolean hasNext = it.hasNext();
  1324.         while (hasNext) {
  1325.             final K key = it.next();
  1326.             final V value = it.getValue();
  1327.             buf.append(key == this ? "(this Map)" : key)
  1328.                 .append('=')
  1329.                 .append(value == this ? "(this Map)" : value);

  1330.             hasNext = it.hasNext();
  1331.             if (hasNext) {
  1332.                 buf.append(CollectionUtils.COMMA).append(' ');
  1333.             }
  1334.         }

  1335.         buf.append('}');
  1336.         return buf.toString();
  1337.     }

  1338.     /**
  1339.      * Updates an existing key-value mapping to change the value.
  1340.      * <p>
  1341.      * This implementation calls {@code setValue()} on the entry.
  1342.      * Subclasses could override to handle changes to the map.
  1343.      * </p>
  1344.      *
  1345.      * @param entry  the entry to update
  1346.      * @param newValue  the new value to store
  1347.      */
  1348.     protected void updateEntry(final HashEntry<K, V> entry, final V newValue) {
  1349.         entry.setValue(newValue);
  1350.     }

  1351.     /**
  1352.      * Gets the values view of the map.
  1353.      * Changes made to the view affect this map.
  1354.      * To simply iterate through the values, use {@link #mapIterator()}.
  1355.      *
  1356.      * @return the values view
  1357.      */
  1358.     @Override
  1359.     public Collection<V> values() {
  1360.         if (values == null) {
  1361.             values = new Values<>(this);
  1362.         }
  1363.         return values;
  1364.     }
  1365. }