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

Reply via email to