RFR(m): JEP 269 initial API and skeleton implementation (JDK-8139232)

Stuart Marks stuart.marks at oracle.com
Tue Nov 24 18:43:13 UTC 2015



On 11/24/15 4:21 AM, Aleksey Shipilev wrote:
> On 11/24/2015 09:26 AM, Stuart Marks wrote:
>> Webrev:
>>
>>      http://cr.openjdk.java.net/~smarks/reviews/jep269/webrev.20151123/
>
>   * It is mildly puzzling why the HashMap initial capacity is different
> from the number of elements you are about to push -- need to spell out
> that we are adjusting for the default HashMap load factor?
>
>   * HashMap would round up the capacity to the next power of two, which
> means you can just either use the default capacity (16) in third of the
> cases, and/or specialize for a step lower capacity (4/8) for smaller
> methods? This saves load-factor-dependent computation.

The main goals here are to prevent the HashMap from being resized/rehashed 
during the loading process, and to have the HashMap be of minimal size for the 
number of mappings being loaded. Since we know the number of mappings we want to 
load, we should provide some number to "capacity" argument of the HashMap 
constructor.

The wrinkle is that this "capacity" is not actually the number of mappings that 
can be stored without resizing, but is the number of *buckets*; that is, as you 
point out, it's load factor dependent. So if we want to load a map with N 
elements without it resizing, we have to provide ceil(N/LF) as the "capacity." 
This is the origin of the magic, puzzling numbers. This is probably worth a comment.

As you also point out this gets rounded up further by HashMap, so an alternative 
is to provide nextPowerOfTwo(ceil(N/LF)). This doesn't save anything AFAICS 
because HashMap still goes through the arithmetic. And this is the number of 
buckets, so we still have to go through an (implicit) load factor computation to 
get this value from the number of mappings. So... would specifying different 
constants be any better?

>   * Map.of(E... es). Is this a suggested strategy to deal with arrays?
> Why not follow Guava's example with doing Map.of(E e1, .. E e11, E...
> others) to avoid confusion with arrays? If there is a reason, I must
> have overlooked it in JEP description and/or code comments.

There's no Map.of(...) varargs call; it's Map.ofEntries(Entry...). I assume you 
meant List.of(...) and Set.of(...)? Those are the ones where Guava, has several 
fixed parameters before the varargs parameter in the trailing position.

The reason for having a single-arg varargs overload is that it's kind of an 
escape hatch. If you want to create one of these collections with N elements, 
where N is unknown at compile time, you can create an array and just pass it in.

s'marks



More information about the core-libs-dev mailing list