2016-04-19 15 views
9

Anche se ho il sospetto che la risposta sia "Non è specificato" ...In che modo Stream.max() gestisce l'uguaglianza?

Se ci sono più "grandi/più bassi" elementi in un Stream cui il Comparator passò ai max o min metodi considera uguale (restituisce 0) , è specificato da qualche parte quale elemento verrà trovato?

+5

Sembra non essere definito comportamento. –

+3

Immagino che dipenda dalla collezione sottostante. – munyengm

+2

Domanda laterale: perché è importante? – Tunaki

risposta

3

È davvero difficile estrarre una dichiarazione definitiva dalla documentazione. Se proviamo a trarre una conclusione dalla descrizione generale del processo di "Riduzione" e da accenni simili alla documentazione, sembrerà sempre che stiamo facendo troppa interpretazione.

Tuttavia, c'è un explicit statement regarding this matter da Brian Goetz che è piuttosto un autorità per quanto riguarda l'API Stream:

Se il flusso viene ordinato (come ad esempio i flussi si ottiene da un array o List), restituisce il prima elemento che è massimale nel caso di più elementi massimali; solo se lo stream non è ordinato è consentito selezionare un elemento arbitrario.

E 'un peccato che una dichiarazione così esplicita non è fatta proprio alla documentazione dei Stream.max, ma almeno è in linea con la nostra esperienza e conoscenza della realizzazione (those of us who looked at the source code). E non dimenticare, considerazioni pratiche, poiché è facile dire "sceglierne uno piuttosto che prima" tramite lo unordered().max(comparator) con lo stato attuale anziché pronunciare "scegli prima piuttosto che qualsiasi" se lo max è stato autorizzato a scegliere un elemento arbitrario in primo luogo .

+2

Penso che l'affermazione esplicita non valga troppo perché ci sono implementazioni di 'Stream' di terze parti non controllate dagli sviluppatori JDK. E se i javadocs non vincolano queste implementazioni, allora sono liberi di gestire questo caso come vogliono. – the8472

+2

@ the8472: davvero? Assegna almeno uno ... – Holger

+2

@ the8472: nota che questa affermazione non si trova nello spazio vuoto. Come già detto nella risposta, * ci sono * diversi aspetti della documentazione che permettono di trarre una tale conclusione; questa affermazione esplicita è solo una buona prova che non stiamo sovra-interpretando qui. – Holger

4

Dopo aver letto il codice sorgente, penso che dovrebbe essere il primo elemento più grande verrà trovato in base all'ordine di raccolta. Siamo in grado di controllare il codice sorgente del Stream.max(Comparator<? super T> comparator), la classe di implementazione è ReferencePipeline.max

@Override 
    public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) { 
     return reduce(BinaryOperator.maxBy(comparator)); 
    } 

che si può vedere, quando si chiama il Stream.max, vuoi dire chiamare il Stream.reduce(BinaryOperator<P_OUT> accumulator)

E guardare il codice sorgente di BinaryOperator.maxBy(comparator)

public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { 
     Objects.requireNonNull(comparator); 
     return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; 
    } 

E 'chiaro, quando a uguale b, restituisce a. Quindi, quando ci sono più elementi "più grandi/più bassi" in un flusso, l'elemento "più grande/più basso" dovrebbe essere il primo elemento "più grande/più basso" in base all'ordine di raccolta

C'è un esempio a blew, solo per il tuo riferimento.

 List<Student> list = Arrays.asList(new Student("s1", 1), new Student("s2", 5), new Student("s3", 3), new Student("s4", 5)); 
     // it should be student of 's2' 
     list.stream().max(Comparator.comparing(Student::getScore)); 
     // it should be student of 's4' 
     list.stream().reduce((a, b) -> Comparator.comparing(Student::getScore).compare(a, b) > 0 ? a : b); 
+2

Dipende molto dall'ordine del flusso. Maggiori informazioni qui http://stackoverflow.com/a/29218074/1743880 – Tunaki

+1

@Tunaki: Grazie Tunaki, imparo molto. :) – Tony

+4

La fonte è informativa, ma non normativa. Non puoi fare affidamento su cose se non fanno parte della documentazione. – the8472

Problemi correlati