RFR(m): JEP 269 initial API and skeleton implementation (JDK-8139232)
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:
> * 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
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.
More information about the core-libs-dev