On 10/14/15 10:56 AM, Kevin Bourrillion wrote:
(Sorry that Guava questions were asked and I didn't notice this thread sooner.)
Hi Kevin, thanks for this feedback. It's still timely, as it's helping to
improve the proposal.
Note that we have empirically learned through our Lists/Sets/Maps factory
classes that varargs factory methods for /mutable/ collections are almost
entirely useless. For one thing, it's simply not common to have a hardcoded
set of initial values yet still actually need to modify the contents later.
When that does come up, the existing workarounds just aren't bad at all: [...]
Anyway, since we created these methods, they became an attractive nuisance,
and thousands of users reach for them who would have been better off in every
way using an immutable collection. Our fondest desire is to one day be able to
delete them. So, obviously, my strong recommendation is not to add these to
ArrayList, etc.
This is very, very interesting.
I have to admit that our rationale in proposing to add the factories to the
concrete implementations is fairly weak. It was something along the lines of,
"Well these will /obviously/ be useful, so let's go ahead and add them."
(Perhaps this is similar to the rationale for adding them to Guava in the first
place.)
Based on your experience, and feedback from other replies to this email, I'm
strongly leaning toward removing the factories from the concrete collections.
It could be that not having these would be a mistake. But if it is, it's easier
to add them later, than it is to add them now and to try to remove them later if
we determine that they were a mistake. (As Dr Deprecator is all too aware.)
The class static method inheritance issue is an annoyance, but I don't think
it's central to the problem. If we were to add static factories to classes, I'm
confident we'd come up with some way to deal with the issue. What I think /is/
central to the issue is what you described as an "attractive nuisance." If the
presence of these methods is likely to cause them to be misused more often then
not, then that's a good reason not to have the API there at all.
More discussion below...
On Fri, Oct 9, 2015 at 4:11 PM, Stuart Marks <stuart.ma...@oracle.com
<mailto:stuart.ma...@oracle.com>> wrote:
Now, Guava handles this use case by providing a family of copying
factories that can accept an array, a Collection, an Iterator, or an
Iterable. These are all useful, but for JEP 269, we wanted to focus on the
"collection literal like" APIs and not expand the proposal to include a
bunch of additional factory methods. Since we need to have a varargs
method anyway, it seemed reasonable to arrange it so that it could easily
accept an array as well.
A decision to support only varargs and arrays is reasonable. However, I don't
see the advantage in using the same method name for both. In Guava, it's clear
what the difference between ImmutableList.of(aStringArray) and
ImmutableList.copyOf(aStringArray) is.
There's a small, but not fundamental, advantage to having the same name.
Suppose we have fixed-arg variants up to 5 and a one-arg varargs method:
List.of(T, T, T, T, T)
List.of(T...)
Then it becomes possible to write,
List<String> list = List.of("a", "b", "c", "d", "e");
and later modify it to
List<String> list = List.of("a", "b", "c", "d", "e", "f");
without having to worry about renaming the method call. Of course, we could
solve this by changing the varargs variant so that the varargs parameter occurs
after all the fixed parameters, like Guava:
List.of(T, T, T, T, T, T, T...)
But then we'd need to add another method to handle the array case:
List.copyOf(T[])
It's not a huge deal to add another method, I suppose. The only disadvantage I'm
aware with List.of(T...) is that it makes it harder to have a list of an array.
Are there other disadvantages?
3. Duplicate handling.
My current thinking is for the Set and Map factories to throw
IllegalArgumentException if a duplicate element or key is detected.
+1
Great, thanks.
To the other question: the reason we chose 11 as the cutoff is that we
determined that there would be no logical basis for exactly where to do it, so
we looked for an illogical basis. Sometimes you'll be at 10, all the way up,
you're at 10 and where can you go from there? Where? Nowhere. So this way, if
we need that extra push over the cliff, we can go up to 11.
It seems there are only two interesting numbers in software development, 11 and
42. In this case 42 is right out, so that leaves 11.
s'marks