2015-11-02 1 views
5

Java 8 introduce un nuovo metodo predefinito nell'interfaccia List per ordinarlo. E 'firma è:Perché list.sort non utilizza l'API opzionale

void sort(Comparator<? super E> c) 

La documentazione dice:

Se il comparatore specificato è nullo, allora tutti gli elementi in questo elenco devono implementare l'interfaccia Comparable e naturale ordinamento degli elementi dovrebbe essere usato.

Quindi, se si desidera ordinare l'elenco da esso è ordine naturale (e che gli elementi sono confrontabili) si hanno a che fare list.sort(null); che è un po 'strano del mio parere.

Se hanno utilizzato un Optional, il documento dichiarerebbe che è possibile fornire facoltativamente un comparatore e che se non viene fornito presupporrà che gli elementi siano già comparabili.

Una chiamata list.sort(null); si trasforma in list.sort(Optional.empty());.

Poiché è un metodo che è esposto al mondo esterno, lo troverei più preciso.

Perché non hanno usato la nuova API Opzionale invece?

+0

... o semplicemente ti costringono a passare in un comparatore non nullo. Penserei che sarebbe molto più semplice a tutto tondo. –

+3

... o corrisponde a 'Collezioni', che fornisce un overload' ordinamento() 'che non accetta alcun argomento' Comparator' da ordinare secondo l'ordine naturale? – rgettman

+3

Oppure basta passare a 'Comparator.naturalOrder()', non è così difficile, e anche molto più chiaro di 'null'. –

risposta

12

Opzionale è destinato all'uso come tipo di reso. Questo è sempre stato il mantra degli sviluppatori JDK-8. Quindi non infrangeranno la loro regola usandola come argomento.

Detto questo, avrei fatto l'argomento obbligatorio, e quindi costringere lo sviluppatore di utilizzare

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

Anche se posso passare nulla, trovo quanto sopra più leggibile, e non molto più dettagliato. Quindi è quello che uso nel mio codice.

+0

Non sapevo del primo paragrafo e sono d'accordo con il tuo ultimo punto. Grazie :) – user2336315

+1

Vedi http://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type per una spiegazione più lunga sull'intenzione, da Brian Goetz stesso (lo sviluppatore principale di JDK8 - o qualsiasi altra cosa il suo vero titolo è) –

+0

Grazie. Avrebbero potuto fornire anche un metodo predefinito senza argomenti comunque. – user2336315

1

Il metodo predefinito è la delega a Arrays#sort, che è has existed since at least Java 1.7.

Ecco il frammento di rilevante per il metodo predefinito:

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

Osservare che sta convertendo l'elenco in un array e lasciando Arrays#sort gestirlo da lì. Il comportamento predefinito per questo poi ricadrà su ciò che è supportato per quel metodo.

Ci sono due ragioni per cui vedo questo essere preferibile l'aggiunta di un Optional:

  • Se non hanno un Comparator da usare, o vogliono solo il comportamento di "default", si può fornire un null ad esso. In questo contesto, null e Optional.isPresent() hanno lo stesso scopo e non guadagnano punti di usabilità.

    È un fastidio dover fornirenull a una funzione per il suo comportamento predefinito; un design migliore potrebbe essere stato quello di sovraccaricare il metodo o consentire invece di passare un'istanza predefinita naturalOrder.

  • Il modello Optional è più destinata ad evitare la manipolazione inavvertitamente un riferimento null, invece di essere utilizzato per un controllo null. Il sovraccarico nell'aggiunta di Optional dove un semplice controllo null sarebbe di gran lunga superiore ai suoi benefici, soprattutto considerando che non vi è alcuna differenza semantica.

+0

C'è anche 'Arrays.sort (Object [] o)' in modo che possano portarlo da lì a seconda se il valore è presente o meno. Mi hai convinto sul tuo ultimo punto, quindi +1. – user2336315

+0

Se lo facessero, ignorerebbero il parametro passato che è * terribile * design.Al minimo, l'utente come * possibilità * di fornire il proprio 'Comparator', ma se decide di passare' null', allora l'ordine naturale vince. – Makoto

+0

Non è convincente. Se il parametro era 'Optional', la delega a' Arrays.sort' richiedeva semplicemente una semplice chiamata a 'oElse (null)' per convertire un 'Optional ' in un 'Comparatore' con valori nulli. Ma una singola implementazione particolare non dovrebbe essere la forza trainante di un design API comunque (e non lo è). A proposito, se un metodo non ha marcatore "Since", di solito è vecchio quanto la classe stessa, che è nel caso di 'java.util.Arrays'" * Da: 1.2 * " – Holger