Mentre studiavo i modi per convertire array primitivi in stream, ho scoperto che char[]non sono supportati mentre sono supportati altri tipi di array primitivi. Qualche motivo particolare per lasciarli fuori nel flusso?
Mentre studiavo i modi per convertire array primitivi in stream, ho scoperto che char[]non sono supportati mentre sono supportati altri tipi di array primitivi. Qualche motivo particolare per lasciarli fuori nel flusso?
Risposte:
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?
BooleanStreamsarebbe inutile": perché?
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.
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.
while (i < limit), ma in nessun caso qualcuno deve farlo [usando le istruzioni di assemblaggio di salti e salti]"
<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>
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.
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).
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
100K+ of JDK footprint?
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.
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.