JDK-8189407 : Add a java.util.Properties constructor that takes an initial capacity
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.util
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 10
  • Submitted: 2017-10-16
  • Updated: 2017-10-31
  • Resolved: 2017-10-26
Related Reports
CSR :  
Description
Summary
-------

Add a new constructor to java.util.Properties that accepts an initial capacity.

Problem
-------

There is currently no way to give a capacity hint to java.util.Properties.  Properties' superclass, Hashtable, accepts such a hint, as do other commonly used Map implementations (HashMap, ConcurrentHashMap).  One consequence is that extra time is spent at startup to expand Properties' storage while initializing system properties.  Startup time could be reduced by being able to specify sufficient storage when a Properties is created.

Solution
--------

A new constructor should be added to java.util.Properties that accepts an int argument to use as an initial capacity.

Given this value will be used to configure the Properties' internal ConcurrentHashMap,
it is convenient and sensible to interpret the value as ConcurrentHashMap does.  Specifically, 
the value represents the number of elements that can be stored without expanding (rather than as the number of buckets, as in Hashtable).

The new constructor matches the corresponding constructor in Properties' parent class, java.util.Hashtable.  Hashtable also has constructors for specifying load factor.
Although Properties inherits load factor from Hashtable (e.g. it's present in the serialized form), it
it does not use the load factor.  This fact is worth documenting.

The other Properties constructors will be updated to call out that their initial capacity is unspecified.

Specification
-------------

    +++ b/src/java.base/share/classes/java/util/Properties.java     Thu Oct 26 12:22:21 2017 -0700
    @@ -121,6 +121,10 @@
      * <p>This class is thread-safe: multiple threads can share a single
      * {@code Properties} object without the need for external synchronization.
      *
    + * @apiNote
    + * The {@code Properties} class does not inherit the concept of a load factor
    + * from its superclass, {@code Hashtable}.
    + * 
      * @author  Arthur van Hoff
    @@ -152,14 +156,35 @@
     
         /**
          * Creates an empty property list with no default values.
    +     * 
    +     * @implNote The initial capacity of a {@code Properties} object created
    +     * with this constructor is unspecified.
          */
         public Properties() {
             this(null);
         }
     
    +    /**
    +     * Creates an empty property list with no default values, and with an
    +     * initial size accommodating the specified number of elements without the
    +     * need to dynamically resize.
    +     *
    +     * @param  initialCapacity the {@code Properties} will be sized to
    +     *         accommodate this many elements 
    +     * @throws IllegalArgumentException if the initial capacity is less than
    +     *         zero.
    +     */
    +    public Properties(int initialCapacity);
    
         /**
          * Creates an empty property list with the specified defaults.
          *
    +     * @implNote The initial capacity of a {@code Properties} object created
    +     * with this constructor is unspecified.
    +     * 
          * @param   defaults   the defaults.
          */
         public Properties(Properties defaults);


Comments
I think we can take this opportunity to do some extrication, around capacity and load factor.
26-10-2017

Moving to approved.
26-10-2017

Please finalize the draft when it is ready for re-review.
26-10-2017

Historically, we have regretted specifying things like initial capacity for collection classes. This is especially true for Hashtable, where the "initial capacity" is __NOT__ the number of elements the Hashtable can hold. It looks like you are using "initial capacity" in a different meaning from the definition in Hashtable.I would probably leave it unspecified, and if we were to specify it, then be consistent with the superclass Hashtable (8 vs 11 !) Yes, Hashtable/Properties is a design mistake morass that's hard to extricate from. But Properties is-a Hashtable, we should play by Hashtable's rules.
24-10-2017

I have updated the other Properties constructors to specify initial capacity, as seen in similar collections (Hashtable, HashMap, etc).
24-10-2017

Voting with comments to approve the request. Should the existing constructors have comments added noting what their implicit capacities are, perhaps as @implNotes? Does the new constructor need to be public? It doesn't seem worthwhile to augment the subclass java.security.Provider as part of this work.
21-10-2017