Collections.emptyList().sort() does nothing

Peter Levart peter.levart at gmail.com
Thu Nov 16 13:55:22 UTC 2017


Hi,

On 11/15/2017 12:18 PM, Vitaly Davidovich wrote:
> On Wed, Nov 15, 2017 at 5:21 AM Andrej Golovnin <andrej.golovnin at gmail.com>
> wrote:
>
>>> On 15/11/17 10:03, Andrej Golovnin wrote:
>>>> I think we would need to write ugly code in any case as Java 9 has now
>>>> two empty list implementations: Collections.emptyList() and List.of().
>>>>
>>>> Collections.emptyList().sort() does not throw an exception.
>>>>
>>>> List.of().sort() throws an exception.
>>> Well, that's a bug.  Sorting an empty list is perfectly valid, and
>> application
>>> programmers shouldn't have to special-case it.
>> I don't think so. I would say that the implementation of
>> Collections.emptyList() is broken. Collections.emptyList() and
>> List.of() are not only empty lists. They are also immutable per
>> specification.
>>
>> Here is another example of an unsortable empty list:
>>
>> Collections.unmodifiableList(Collections.emptyList()).sort() throws an
>> exception.
> One can argue that since those are empty by construction/design, sorting
> them is not a bug.  That’s different from, say, trying to sort an
> unmodifiable list that happens to be empty and not failing in that case.
>
>  From a user’s perspective, I agree it’s annoying to have to special case
> these.  This is particularly so because immutability is not expressed in
> the types or type system.

There are 3 kinds of List(s) in JDK according to which optional methods 
are supported and which throw UOE:

A - normal mutable lists (ala ArrayList)
B - immutable/unmodifiable lists (ala Collections.unmodifiableList(...), 
List.of(...))
C - structurally unmodifiable mutable lists (ala Arrays.asList(...))

What is Collections.emptyList()? In terms of the original (as of jdk 1.2 
API), it can be either B or C. Additional (default) List methods added 
later may blur this distinction, but they can only do that "artificially".

Suppose that you have and API where you want to return List(s) of type C 
to the user, so that user may choose to consume them as-is or sort them 
1st in-place. What list would you return when you have 0 elements to 
return? Would you return Collections.emptyList() and instruct the user 
that he may not blindly sort any given List he gets, but only those that 
are not empty? Would you rather return Arrays.asList() and create new 
object every time? Why can't I have both?

Well, I can have both:

     private static final List<T> EMPTY_LIST = Arrays.asList();

     ...
     return EMPTY_LIST;
}


But this is complicated and has to be done over and over again. It's 
like the story of empty array(s) that have to be declared as a private 
static final field in each and every class which wants to optimize empty 
returns.

Not to mention that changing Collections.emptyList().sort() to throw UOE 
is an incompatible change. Programs may already use emptyList() as kind 
C list and depend on it. So why would not Collections.emptyList() be 
simply declared to be of kind C and that's it. No code to change and no 
code to break. If one wants to get an empty list of type B, he should 
use List.of().

Regards, Peter

>
>>
>>> --
>>> Andrew Haley
>>> Java Platform Lead Engineer
>>> Red Hat UK Ltd. <https://www.redhat.com>
>>> EAC8 43EB D3EF DB98 C
>> <https://maps.google.com/?q=EF+DB98+C&entry=gmail&source=g>C77 2FAD A5CD
>> 6035 332F A671
>>



More information about the core-libs-dev mailing list