2015-11-02 14 views
5

Java 8 führt eine neue Standardmethode für die Schnittstelle List ein, um sie zu sortieren. Es ist Signatur:Warum list.sort die optionale API nicht verwendet

void sort(Comparator<? super E> c) 

Die Dokumentation sagt:

Wenn der angegebene Komparator null ist, werden alle Elemente in dieser Liste müssen die Comparable-Schnittstelle implementieren und die natürliche Ordnung Elemente verwendet werden soll.

Also, wenn Sie die Liste sortieren möchten, indem sie natürliche Ordnung ist (und dass Ihre Elemente vergleichbar sind), müssen Sie list.sort(null); tun, welche Art von seltsam meiner Meinung.

Wenn sie eine Optional verwendet, würde das Dokument angeben, dass Sie optional einen Komparator bereitstellen können, und dass, wenn es nicht bereitgestellt wird, es die Elemente bereits vergleichbar annehmen wird.

Ein list.sort(null); Anruf würde in list.sort(Optional.empty()); umgewandelt werden.

Da es eine Methode ist, die es der Außenwelt aussetzt, würde ich es genauer finden.

Warum haben sie nicht stattdessen die neue optionale API verwendet?

+0

... oder erzwingen Sie nur, dass Sie einen Nicht-Null-Vergleicher übergeben. Ich denke, das wäre viel einfacher. –

+3

... oder passen Sie 'Collections' an, was eine Überladung' sort() 'liefert, die keine 'Comparator'-Argumente benötigt, um nach der natürlichen Reihenfolge zu sortieren? – rgettman

+3

Oder pass einfach 'Comparator.naturalOrder()', es ist nicht so schwer und auch viel klarer als 'null'. –

Antwort

12

Optional ist als Rückgabetyp vorgesehen. Das war schon immer das Mantra der JDK-8-Entwickler. Also werden sie ihre eigene Regel nicht brechen, indem sie sie als Argument verwenden.

Das heißt, würde ich das Argument zwingend gemacht haben, und damit die Entwickler zwingen

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

Selbst zu verwenden, wenn ich null passieren kann, finde ich die oben lesbarer und nicht viel ausführlicher. Das ist, was ich in meinem Code verwende.

+0

Ich wusste nichts über den ersten Absatz, und ich stimme Ihrem letzten Punkt zu. Danke :) – user2336315

+1

Siehe http://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type für eine längere Erklärung der Absicht, von Brian Goetz selbst (der führende JDK8-Entwickler - oder was auch immer sein eigentlicher Titel ist) –

+0

Danke. Sie hätten auch eine Standardmethode ohne Argumente bereitstellen können. – user2336315

1

Die Standardmethode delegiert an Arrays#sort, die has existed since at least Java 1.7.

Hier ist der relevante Code-Schnipsel für die Standard-Methode:

@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); 
    } 
} 

Beachten Sie, dass sie die Liste in ein Array Converting und lassen Arrays#sort es von dort behandeln. Das Standardverhalten würde dann auf das zurückgreifen, was für diese Methode unterstützt wird.

Es gibt zwei Gründe, warum ich sehe dies bevorzugt ist die Zugabe eines Optional:

  • Wenn Sie nicht tun haben ein Comparator zu verwenden, oder wollen einfach nur die „Standard“ -Verhalten, können Sie Stellen Sie eine null zur Verfügung. In diesem Zusammenhang dienen null und Optional.isPresent() dem gleichen Zweck und würden keine Nutzbarkeitspunkte verdienen.

    Es ist ein Ärgernis zu null zu einer Funktion für sein Standardverhalten zu haben; Besseres Design könnte sein, entweder die Methode zu überlasten oder eine Standard naturalOrder Instanz zuzulassen, die stattdessen übergeben wird.

  • Optional Das Muster wird mehr gemeint versehentlich zum Schutz gegen eine Referenz null Handhabung, im Gegensatz zu einer null Prüfung verwendet werden. Der Overhead beim Hinzufügen von Optional, bei dem eine einfache null Prüfung ausreichen würde, würde deren Vorteile bei weitem überwiegen, insbesondere wenn man bedenkt, dass es keinen semantischen Unterschied gibt.

+0

Es gibt auch 'Arrays.sort (Object [] o)', so dass sie von dort zu je nachdem nehmen können, ob der Wert vorhanden ist oder nicht. Du hast mich aber bei deinem letzten Punkt überzeugt, also +1. – user2336315

+0

Wenn sie das taten, würden sie den Parameter ignorieren, der * schrecklich * Design ist.Im Minimum, der Benutzer als die * Chance *, ihre eigenen 'Comparator' zur Verfügung zu stellen, aber wenn sie sich entscheiden," null "zu übergeben, dann gewinnt die natürliche Reihenfolge. – Makoto

+0

Das überzeugt nicht. Wenn der Parameter 'Optional' war, erforderte das Delegieren an' Arrays.sort' nur einen einfachen Aufruf von 'orElse (null)', um ein 'Optional ' in einen nullbaren 'Comparator' umzuwandeln. Aber eine einzelne bestimmte Implementierung sollte nicht die treibende Kraft hinter einem API-Design sein (und das ist es auch nicht). Übrigens, wenn eine Methode keinen "Seit" -Marker hat, ist sie normalerweise so alt wie die Klasse selbst, was im Fall von 'java.util.Arrays' ist. * Seit: 1.2 *" – Holger

Verwandte Themen