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