Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why list.sort does not use the Optional API

Tags:

java

java-8

Java 8 introduces a new default method on the List interface to sort it. It's signature is :

void sort(Comparator<? super E> c)

The documentation says:

If the specified comparator is null then all elements in this list must implement the Comparable interface and the elements' natural ordering should be used.

So if you want to sort the list by it's natural order (and that your elements are comparable) you have to do list.sort(null); which is kind of weird of my opinion.

If they used an Optional the doc would stated that you can optionally provide a comparator, and that if it's not provided it will assume the elements are already comparable.

A list.sort(null); call would be transformed into list.sort(Optional.empty());.

As it's a method that it exposed to the outside world, I would find it more accurate.

Why didn't they used the new Optional API instead?

like image 326
user2336315 Avatar asked Nov 02 '15 21:11

user2336315


People also ask

Is null better than optional?

In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.

What is optional API in Java?

Optional is a container object which may or may not contain a non-null value. You must import java. util package to use this class. If a value is present, isPresent() will return true and get() will return the value.

Which sorting algorithm does sort () method use in Java?

Java's Arrays. sort method uses quicksort, insertion sort and mergesort. There is even both a single and dual pivot quicksort implemented in the OpenJDK code.


2 Answers

Optional is intended to be used as a return type. That has always been the mantra of the JDK-8 developers. So they won't break their own rule by using it as an argument.

That said, I would have made the argument mandatory, and thus force the developer to use

list.sort(Comparator.<Foo>naturalOrder());

Even if I can pass null, I find the above more readable, and not much more verbose. So that's what I use in my code.

like image 50
JB Nizet Avatar answered Sep 20 '22 07:09

JB Nizet


The default method is delegating to Arrays#sort, which has existed since at least Java 1.7.

Here's the relevant snippet for the default method:

@SuppressWarnings({"unchecked", "rawtypes"})
default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for (Object e : a) {
        i.next();
        i.set((E) e);
    }
}

Observe that it's converting the list into an array and letting Arrays#sort handle it from there. The default behavior for this then would fall back to what is supported for that method.

There are two reasons why I see this being preferable to adding an Optional:

  • If you don't have a Comparator to use, or just want the "default" behavior, you can provide a null to it. In this context, null and Optional.isPresent() serve the same purpose and would not earn any usability points.

    It is an annoyance to have to provide null to a function for its default behavior; better design might have been to either overload the method or allow a default naturalOrder instance to be passed in instead.

  • The Optional pattern is more meant to guard against inadvertently handling a null reference, as opposed to being used for a null check. The overhead in adding Optional where a simple null check would suffice would far outweigh its benefits, especially considering that there is no semantic difference.

like image 35
Makoto Avatar answered Sep 22 '22 07:09

Makoto