< prev index next >

src/java.base/share/classes/java/util/HashMap.java

Print this page

        

@@ -499,13 +499,13 @@
                 float ft = ((float)s / loadFactor) + 1.0F;
                 int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                          (int)ft : MAXIMUM_CAPACITY);
                 if (t > threshold)
                     threshold = tableSizeFor(t);
+            } else if (s > threshold) {
+                resize(s);
             }
-            else if (s > threshold)
-                resize();
             for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
                 K key = e.getKey();
                 V value = e.getValue();
                 putVal(hash(key), key, value, false, evict);
             }

@@ -659,10 +659,33 @@
         afterNodeInsertion(evict);
         return null;
     }
 
     /**
+     * Resize the table to the nearest power of two to {@code size}. Moves all items to the new table.
+     *
+     * @param size expected number of elements in the new table
+     * @return the table
+     */
+    final Node<K, V>[] resize(int size) {
+        if (size < 0) {
+            throw new IllegalArgumentException("Negative number of elements does not make sense.");
+        }
+        Node<K, V>[] oldTable = table;
+        int oldCapacity = (oldTable == null) ? 0 : oldTable.length;
+        int newCapacity = tableSizeFor(size);
+
+        // need to resize?
+        if (newCapacity > oldCapacity) {
+            threshold = (int) ((float) newCapacity * loadFactor);
+            return createTableAndMoveElements(newCapacity, oldCapacity, oldTable);
+        } else {
+            return oldTable;
+        }
+    }
+
+    /**
      * Initializes or doubles table size.  If null, allocates in
      * accord with initial capacity target held in field threshold.
      * Otherwise, because we are using power-of-two expansion, the
      * elements from each bin must either stay at same index, or move
      * with a power of two offset in the new table.

@@ -693,40 +716,46 @@
             float ft = (float)newCap * loadFactor;
             newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                       (int)ft : Integer.MAX_VALUE);
         }
         threshold = newThr;
-        @SuppressWarnings({"rawtypes","unchecked"})
-        Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
+
+        return createTableAndMoveElements(newCap, oldCap, oldTab);
+    }
+
+    private Node<K, V>[] createTableAndMoveElements(int newCap, int oldCap, Node<K, V>[] oldTab) {
+        @SuppressWarnings({"rawtypes", "unchecked"})
+        Node<K, V>[] newTab = (Node<K, V>[]) new Node[newCap];
         table = newTab;
         if (oldTab != null) {
             for (int j = 0; j < oldCap; ++j) {
-                Node<K,V> e;
+                Node<K, V> e;
                 if ((e = oldTab[j]) != null) {
                     oldTab[j] = null;
-                    if (e.next == null)
+                    if (e.next == null) {
                         newTab[e.hash & (newCap - 1)] = e;
-                    else if (e instanceof TreeNode)
-                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
-                    else { // preserve order
-                        Node<K,V> loHead = null, loTail = null;
-                        Node<K,V> hiHead = null, hiTail = null;
-                        Node<K,V> next;
+                    } else if (e instanceof TreeNode) {
+                        ((TreeNode<K, V>) e).split(this, newTab, j, oldCap);
+                    } else { // preserve order
+                        Node<K, V> loHead = null, loTail = null;
+                        Node<K, V> hiHead = null, hiTail = null;
+                        Node<K, V> next;
                         do {
                             next = e.next;
                             if ((e.hash & oldCap) == 0) {
-                                if (loTail == null)
+                                if (loTail == null) {
                                     loHead = e;
-                                else
+                                } else {
                                     loTail.next = e;
-                                loTail = e;
                             }
-                            else {
-                                if (hiTail == null)
+                                loTail = e;
+                            } else {
+                                if (hiTail == null) {
                                     hiHead = e;
-                                else
+                                } else {
                                     hiTail.next = e;
+                                }
                                 hiTail = e;
                             }
                         } while ((e = next) != null);
                         if (loTail != null) {
                             loTail.next = null;
< prev index next >