ytatichno commented on PR #652:
URL: 
https://github.com/apache/commons-collections/pull/652#issuecomment-3412684581

   Thank you for your instant feedback!
   
   I fully agree that the constructor parameter of HashMap(int initialCapacity) 
is not the same as the table size and that load factor remains constant (0.75) 
regardless input map's loadFactor.
   
   The optimization I proposed is not related to the load factor value itself, 
but to avoiding a resize that can happen when the map is filled exactly up to 
its declared size.
   
   For example, when using new HashMap<>(map.size()), the internal threshold 
becomes (int)(map.size() * 0.75).
   Therefore, after inserting all elements from the source map, in about 50% of 
practical cases the threshold is exceeded and an extra resize occurs.
   
   Using Math.ceil(map.size() / 0.75d) as initial capacity avoids that resize 
and results in a table that is sized exactly to hold all entries without 
rehashing.
   
   This is also consistent with the JDK’s approach in 
HashMap.calculateHashMapCapacity (introduced in Java 19).
   
   Here it is:
   ```
          /**
        * Calculate initial capacity for HashMap based classes, from expected 
size and default load factor (0.75).
        *
        * @param numMappings the expected number of mappings
        * @return initial capacity for HashMap based classes.
        * @since 19
        */
       static int calculateHashMapCapacity(int numMappings) {
           return (int) Math.ceil(numMappings / (double) DEFAULT_LOAD_FACTOR);
       }
   
       /**
        * Creates a new, empty HashMap suitable for the expected number of 
mappings.
        * The returned map uses the default load factor of 0.75, and its 
initial capacity is
        * generally large enough so that the expected number of mappings can be 
added
        * without resizing the map.
        *
        * @param numMappings the expected number of mappings
        * @param <K>         the type of keys maintained by the new map
        * @param <V>         the type of mapped values
        * @return the newly created map
        * @throws IllegalArgumentException if numMappings is negative
        * @since 19
        */
       public static <K, V> HashMap<K, V> newHashMap(int numMappings) {
           if (numMappings < 0) {
               throw new IllegalArgumentException("Negative number of mappings: 
" + numMappings);
           }
           return new HashMap<>(calculateHashMapCapacity(numMappings));
       }
       ```
   
   I can add a short test showing the extra resize if you think it would 
clarify my intentions.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to