5

L'interfaccia Stream ha due sovraccarichi per il metodo of(). Uno di questi è un metodo a variabile, mentre l'altro richiede un singolo argomento.Perché sovraccaricare il metodo varargs di() nell'interfaccia di Java Stream?

Il metodo a un argomento è un ottimizzazione delle prestazioni rispetto al passaggio di un argomento al metodo di variabile-aritmetica? Se sì, come migliora le prestazioni? Le stesse domande potrebbero essere poste al metodo empty(), che sembrerebbe essere la sintassi dello zucchero attorno alla variabile aritmetica of().

Vedo che l'implementazione differisce tra questi metodi, con la differenza che apparentemente è come il Spliterator viene istanziato; ma quale vantaggio offre questa API Stream?

risposta

5

Sì, è un'ottimizzazione per evitare il sovraccarico di creare una matrice per contenere solo un singolo elemento, che è ciò che si otterrebbe se si fosse utilizzata la versione varargs.

Le stesse domande si può chiedere del metodo vuoto(), che sembrerebbe essere lo zucchero sintassi intorno alla variabile arity di versione()

Cosa implementazione stai guardando? Quando guardo l'implementazione non vedo questo.

+0

Intendevo solo che le firme dei metodi sembrerebbero indicare lo zucchero di sintassi (e la documentazione non punta in un modo o nell'altro). Vedo che le implementazioni sono diverse. – jaco0646

+0

L'evitamento di un elemento singolo o di un array vuoto sembra una micro-ottimizzazione. È questo il genere di cose di cui uno sviluppatore medio dovrebbe preoccuparsi? Devo fornire questo tipo di ottimizzazione delle prestazioni per tutti i miei metodi varargs? – jaco0646

+1

@ jaco0646, cosa c'è di sbagliato nello zucchero della sintassi? Soprattutto se offre anche opportunità di ottimizzazione delle prestazioni. –

5

Il flusso vuoto e il flusso di un singolo elemento sono casi d'uso molto comuni, soprattutto quando si utilizza lo .flatMap(). Ad esempio, ecco come Optional.stream() è implemented in Java-9:

public Stream<T> stream() { 
    if (!isPresent()) { 
     return Stream.empty(); 
    } else { 
     return Stream.of(value); 
    } 
} 

Quindi, dato il flusso di optional è possibile scartare nel flusso piatta in questo modo:

streamOfOptionals.flatMap(Optional::stream); 

Qui si crea tonnellate di vuoto stream e flussi di singoli elementi, quindi l'ottimizzazione di questi casi sembra molto ragionevole. In particolare, Stream.empty() a differenza di Stream.of() non crea una matrice vuota e non crea lo splitteratore (riutilizza la stessa istanza dello splitteratore). Stream.of(T) è inoltre particolarmente ottimizzato all'interno dello StreamBuilderImpl, quindi nessun array è allocato per singolo elemento.

1

Mi sono imbattuto in una risorsa ufficiale che conferma le precedenti risposte a questa domanda: JEP 269: Convenience Factory Methods for Collections. La descrizione di questa proposta è quello di,

fornire metodi factory statici sui List, Set e Map interfacce per la creazione di istanze non modificabili di quelle collezioni.

Questi includeranno sovraccarichi di vararg, in modo che non ci sia un limite fisso per la dimensione della raccolta ... Verranno fornite le API del caso speciale (sovraccarico a argomento fisso) per un massimo di dieci elementi. Mentre questo introduce un po 'di confusione nell'API, evita l'allocazione dell'array, l'inizializzazione e il sovraccarico della garbage collection che è sostenuto dalle chiamate varargs.

Quindi l'ottimizzazione delle prestazioni è semplicemente per evitare l'array di un metodo varargs.

Problemi correlati