Hi,

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.

Roger


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.

-Patrick


Am 01.11.2017 um 21:05 schrieb Louis Wasserman <lowas...@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 <patr...@reini.net 
<mailto:patr...@reini.net>> wrote:

Am 01.11.2017 um 20:25 schrieb Stuart Marks <stuart.ma...@oracle.com 
<mailto:stuart.ma...@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.

s'marks
-Patrick

Reply via email to