-
CSR
-
Resolution: Approved
-
P4
-
None
-
source
-
minimal
-
Minimal compatibility risk: adding static methods on concrete classes.
-
Java API
-
SE
Summary
Add methods to create HashSet and LinkedHashSet instances with the appropriate capacity for a given number of elements.
Problem
HashSet and LinkedHashSet have constructors that take an int "capacity" argument. These constructors are useful for pre-sizing a set instance so that a certain number of elements can be added without the set having to resize itself.
The name "capacity" is rather misleading. The capacity is actually the internal table length of the HashMap that backs the HashSet (respectively for LinkedHashMap and LinkedHashSet). The number of elements that can be held in a set is generally 0.75 of its capacity, where 0.75 is the default load factor. To obtain the appropriate capacity for a desired number of elements, one must divide by 0.75 and round up to the next int. In practice, programs perform this computation incorrectly. There are a fair number of locations in the JDK (and by extension, in code "in the wild") that incorrectly pass the expected number of elements directly as the capacity, without even performing the load factor computation. The correct computation should be made available through a library API.
The issues here are very similar to those with HashMap creation. See the discussion in CSR JDK-8284377 covering the addition of HashMap static factory methods.
Solution
Add new static factory methods to HashSet and LinkedHashSet.
The rationale for naming these static factory methods is similar to the HashMap static factory methods. Having the class name in the method name is important, because static methods can be inherited by subclasses. See this comment on the HashMap factory bug report for the rationale for naming and placement of the HashMap static factory methods.
Specification
// java.util.HashSet
/**
* Creates a new, empty HashSet suitable for the expected number of elements.
* The returned set uses the default load factor of 0.75, and its initial capacity is
* generally large enough so that the expected number of elements can be added
* without resizing the set.
*
* @param numElements the expected number of elements
* @param <T> the type of elements maintained by the new set
* @return the newly created set
* @throws IllegalArgumentException if numElements is negative
* @since 19
*/
public static <T> HashSet<T> newHashSet(int numElements)
// java.util.LinkedHashSet
/**
* Creates a new, empty LinkedHashSet suitable for the expected number of elements.
* The returned set uses the default load factor of 0.75, and its initial capacity is
* generally large enough so that the expected number of elements can be added
* without resizing the set.
*
* @param numElements the expected number of elements
* @param <T> the type of elements maintained by the new set
* @return the newly created set
* @throws IllegalArgumentException if numElements is negative
* @since 19
*/
public static <T> LinkedHashSet<T> newLinkedHashSet(int numElements)
- csr of
-
JDK-8284780 Need methods to create pre-sized HashSet and LinkedHashSet
- Resolved