JEP 269: Convenience Factory Methods for Collections

Stuart Marks stuart.marks at oracle.com
Wed Sep 30 03:03:06 UTC 2015


Hi Rémi,

Thanks for looking at the proposal.

We did consider this style of builder as one of the alternatives to what's in 
the JEP. The concern I have about builders such as this is that the number of 
entries isn't available at the time the map is to be built.

For HashMap, this means that a default size has to be chosen. It can either be 
too big, meaning space is wasted, or too small, which means that it has to be 
resized while being built.

For an unmodifiable map, in practical terms it means that the keys and values 
have to be accumulated in a temporary structure before the result map can be 
built. The reason is that we might want to choose different map implementations 
based on the size of the map.

(An additional, though unrelated issue is that in this example, the builder 
holds a reference to the map being constructed. If malicious code were to store 
this builder somewhere, it could be used to modify the result map at unforeseen 
times, leading to misbehavior. Careful coding could avoid such problems, 
possibly at the cost of making defensive copies.)

None of these problems are insurmountable, but it doesn't seem clear to me that 
this or similar builder approaches necessarily have any advantage over the 
varargs-of-entries approach outlined in the JEP. The varargs-of-entries approach 
of course has its own overhead. There is the possibility of the entry objects 
being replaced by value types in a future JDK (at least, Brian thinks this might 
be possible!) so that's what tipped us toward that approach.

s'marks

On 9/25/15 12:32 AM, Remi Forax wrote:
> Hi Mark, hi Stuart, hi all,
>
> for Map, i think a version with a builder will be cool too,
> something like:
>
>    public interface EntryBuilder<K, V> {
>      public EntryBuilder<K,V> entry(K key, V value);
>    }
>
> and by example for HashMap:
>
>    public static <K, V> HashMap<K, V> fromBuilder(Consumer<? super EntryBuilder<K,V>> consumer) {
>      HashMap<K,V> map = new HashMap<>();
>      consumer.accept(new EntryBuilder<>() {
>        public EntryBuilder<K,V> entry(K key, V value) {
>          map.put(key, value);
>          return this;
>        }
>      });
>      return map;
>    }
>
>    ...
>    HashMap<String, Integer> map = HashMap.fromBuilder(b -> b
>      .entry("foo", 1)
>      .entry("bar", 2));
>
> The builder pattern let us to avoid to create intermediary entry objects.
>
> regards,
> Rémi
>
> ----- Mail original -----
>> De: "mark reinhold" <mark.reinhold at oracle.com>
>> À: "stuart marks" <stuart.marks at oracle.com>
>> Cc: core-libs-dev at openjdk.java.net
>> Envoyé: Jeudi 24 Septembre 2015 02:02:17
>> Objet: JEP 269: Convenience Factory Methods for Collections
>>
>> New JEP Candidate: http://openjdk.java.net/jeps/269
>>
>> - Mark
>>



More information about the core-libs-dev mailing list