RFR(m): 8177290 add copy factory methods for unmodifiable List, Set, Map
Roger.Riggs at Oracle.com
Thu Nov 2 19:08:37 UTC 2017
It would also support a more fluent use of the APIs. Though if we start
down that road
it may become littered with convenience methods. Something to ponder
for a bit.
On 11/1/2017 4:29 PM, Patrick Reinhart wrote:
> In this case I would prefer a non static copyOf() method on the list to create a unmodifiable list/set/map, where the optimal factory method can be called. This would also solve the problem of a concurrent implementation.
>> Am 01.11.2017 um 21:05 schrieb Louis Wasserman <lowasser at google.com>:
>> I disagree, actually. Collections with size zero and one are significantly more common than bigger collections.
>> In Guava's immutable collection factories (ImmutableList.of(...) etc.), we observed a roughly exponential decline in the number of users of factory methods of each size: if N people created empty lists, ~N/2 created singleton lists, ~N/4 created two-element lists, etc. We got noticeable pushback from RAM-sensitive customers when we eliminated some specialized singleton collection implementations.
>> Our experience has been that specializing for N=0 and N=1 does pay off. Probably not N=2, though?
>> On Wed, Nov 1, 2017 at 12:45 PM Patrick Reinhart <patrick at reini.net <mailto:patrick at reini.net>> wrote:
>>> Am 01.11.2017 um 20:25 schrieb Stuart Marks <stuart.marks at oracle.com <mailto:stuart.marks at oracle.com>>:
>>> On 10/31/17 5:52 PM, Bernd Eckenfels wrote:
>>>> Having a List.of(List) copy constructor would save an additional array copy in the collector Which uses (List<T>)List.of(list.toArray())
>>> The quickest way to get all the elements from the source collection is to call toArray() on it. Some copy constructors (like ArrayList's) simply use the returned array for internal storage. This saves a copy, but it relies on the source collection's toArray() implementation to be correct. In particular, the returned array must be freshly created, and that array must be of type Object. If either of these is violated, it will break the ArrayList.
>>> The "immutable" collections behind List.of/copyOf/etc. are fastidious about allocating their internal arrays in order to ensure that they are referenced only from within the newly created collection. This requires making an „extra" copy of the array returned by toArray().
>>> An alternative is for the new collection to preallocate its internal array using the source's size(), and then to copy the elements out. But the source’s
>>> size might change during the copy (e.g., if it’s a concurrent collection) so this complicates things.
>> I think the array „overhead“ would be only for the cases of zero, one and two value implementations. That seems to me not worth of optimizing…
>>> I think the only safe way to avoid the extra copy is to create a private interface that can be used by JDK implementations.
More information about the core-libs-dev