Perché char [] è l'unico array non supportato da Arrays.stream ()?


Risposte:


31

Come ha detto Eran, non è l'unico mancante.

A BooleanStreamsarebbe inutile, a ByteStream(se esistesse) può essere gestito come InputStreamo convertito in IntStream(come può short) e floatpuò essere gestito come a DoubleStream.

Dato che charnon è in grado di rappresentare tutti i personaggi (vedi link), sarebbe un po ' un flusso legacy. Sebbene la maggior parte delle persone non abbia comunque a che fare con i punti di codice, può sembrare strano. Voglio dire che usi String.charAt()senza pensare "questo in realtà non funziona in tutti i casi".

Quindi alcune cose sono state escluse perché non sono state ritenute così importanti. Come detto da JB Nizet nella domanda collegata :

I progettisti hanno scelto esplicitamente di evitare l'esplosione di classi e metodi limitando i flussi primitivi a 3 tipi, poiché gli altri tipi (char, short, float) possono essere rappresentati dal loro equivalente più grande (int, double) senza alcuna penalità di prestazione significativa.

Il motivo BooleanStreamsarebbe inutile, perché hai solo 2 valori e questo limita molto le operazioni. Non ci sono operazioni matematiche da fare e quanto spesso lavori con molti valori booleani?


7
"A BooleanStreamsarebbe inutile": perché?
glglgl

12
È davvero irragionevole supporre che qualcuno potrebbe aver bisogno di fare, per esempio reduce(Boolean::logicalAnd)o reduce(Boolean::logicalOr), su un boolean[]? Dopotutto, i metodi logicalAnde logicalOrsono stati aggiunti in Java 8, quindi posso fare queste operazioni di riduzione di un Stream<Boolean>... A proposito, puoi eseguire lo streaming su un modo char[]semplice CharBuffer.wrap(array).chars()o CharBuffer.wrap(array).codePoints(), a seconda di quale semantico preferisci.
Holger,

2
@Holger solo perché Boolean::logicalAndesiste, non garantisce necessariamente l'esistenza di a BooleanStream. Dopotutto, possono essere utilizzati in situazioni lambda non stream. Posso immaginare che qualcuno voglia fare reduce(Boolean::logicalAnd), ma in nessun caso Qualcuno necessità di farlo.
Kayaman,

4
Non vedo quale argomento stai cercando di fare. Nella sua forma estrema: "Posso immaginare che qualcuno vorrebbe fare while (i < limit), ma in nessun caso qualcuno deve farlo [usando le istruzioni di assemblaggio di salti e salti]"
Alexander - Ripristina Monica

11
Mi sembra che l'unica ragione per cui non esiste <Primitive>Streamun tipo primitivo sia perché gonfia troppo l'API. La domanda corretta da porsi è "perché c'è IntStream?" e la sfortunata risposta è perché il sistema di tipi di Java non è abbastanza elaborato per esprimersi Stream<int>senza tutte le spese di prestazioni dell'uso Integer. Se Java avesse tipi di valore, che potrebbero essere allocati nello stack o incorporati direttamente in linea all'interno di altre strutture di dati, non ci sarebbe bisogno di nulla in piùStream<T>
Alexander - Reinstate Monica

32

Certo, la risposta è " perché è quello che hanno deciso i designer ". Non esiste alcun motivo tecnico per cui CharStreamnon potrebbe esistere.

Se vuoi una giustificazione, di solito devi trasformare la mailing list di OpenJDK *. La documentazione del JDK non ha l'abitudine di giustificare perché qualcosa è perché è.

Qualcuno ha chiesto

L'uso di IntStream per rappresentare il flusso char / byte è un po 'scomodo. Dovremmo aggiungere anche CharStream e ByteStream?

La risposta di Brian Goetz (Java Language Architect) dice

Risposta breve: no.

Non vale altri 100 K + di impronta JDK ciascuno per questi moduli che non vengono usati quasi mai. E se aggiungessimo quelli, qualcuno richiederebbe short, float o booleano.

Detto in altro modo, se le persone insistessero sul fatto che avevamo tutte le specializzazioni primitive, non avremmo specializzazioni primitive. Quale sarebbe peggio dello status quo.

fonte

Lo dice anche altrove

Se vuoi gestirli come caratteri, puoi trasferirli in caratteri abbastanza facilmente. Non sembra un caso d'uso abbastanza importante per avere un'intera serie di flussi. (Lo stesso con Short, Byte, Float).

fonte

TL; DR: non vale i costi di manutenzione.


* Se sei curioso, la query di Google che ho usato era

site:http://mail.openjdk.java.net/ charstream

2
Qualcuno potrebbe chiarire cosa intendono 100K+ of JDK footprint?
yassin,

3
@yassin Qualcuno deve scrivere il codice. Stima che ogni specializzazione dello stream sia più di 100.000 righe di codice
Michael

3
@BulgarSadykov Tali domande sul " perché X è come Y " sono spesso chiuse come opinioni perché è impossibile leggere la mente dell'autore originale e, a meno che non si presentino, tutto ciò che otterrai è una congettura. Se chiedo "come posso inviare una richiesta POST con il client HTTP di Apache?", Chiunque abbia familiarità con la libreria può rispondere. Perché una biblioteca è progettata così com'è è di solito impossibile rispondere. L'unico motivo per cui siamo in grado di rispondere davvero è perché c'è un registro pubblico delle loro conversazioni. Questo è quello che stavo cercando di ottenere con la prima frase.
Michael,

2
@BulgarSadykov si ricorda anche di questo, cita il blog di Eric Lippert, su C #, ma sul tema del "perché funzione Foo non è implementata nella lingua" stackoverflow.com/a/5588850/479251
Pac0

2
@BulgarSadykov Rispettosamente in disaccordo. Ancora una volta, ripeto la mia domanda di esempio di " come posso inviare una richiesta POST con il client HTTP di Apache? ". Una risposta a questa domanda chiaramente non inizia con " perché è quello che hanno deciso i designer ". Non sto cambiando la formulazione, scusa.
Michael,

7

Non sono solo le charmatrici che non sono supportate.

Ci sono solo 3 tipi di flussi primitivi - IntStream, LongStreame DoubleStream.

Come risultato, Arraysha metodi che convertono int[], long[]e double[]alle corrispondenti flussi primitivi.

Non esistono metodi corrispondenti per boolean[], byte[], short[], char[]e float[], poiché questi tipi primitivi hanno alcun corrispondente flussi primitive.


4
"Poiché questi tipi primitivi non hanno flussi primitivi corrispondenti." Quindi la domanda di follow-up sarebbe "perché"?
Federico Klez Culloca,

7
@FedericoklezCulloca a questa domanda di risposta viene data una risposta qui
Eran,

6

charè una parte dipendente di String- memorizzazione dei valori UTF-16. Un simbolo Unicode, un punto di codice , a volte è una coppia surrogata di caratteri. Quindi qualsiasi soluzione semplice con caratteri copre solo una parte del dominio Unicode.

C'è stato un tempo che charaveva il suo diritto di essere di tipo pubblico. Ma al giorno d'oggi è meglio usare i punti di codice , un IntStream. Un flusso di caratteri non è in grado di gestire in modo diretto coppie surrogate.

L'altro motivo più prosaico è che il modello di "processore" JVM utilizza un int"registro" come il più piccolo, mantenendo valori booleani, byte, short e anche caratteri in una posizione di archiviazione di dimensioni tali. Per non gonfiare necessariamente le classi java, una trattenuta da tutte le possibili varianti di copia.

In un futuro molto lontano ci si potrebbe aspettare che i tipi primitivi possano funzionare come parametri di tipo generico, fornendo a List<int>. Quindi potremmo vedere a Stream<char>.

Per il momento meglio evitare char, e forse usare java.text.Normalizerper una forma canonica unica di punti di codice / stringhe Unicode.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.