Mentre esaminavo i modi per convertire gli array primitivi in stream, ho trovato che char[]
non sono supportati mentre altri tipi di array primitivi sono supportati. C'è qualche ragione particolare per lasciarli fuori nello stream?
Naturalmente, la risposta è "perché così hanno deciso i progettisti". Non c'è nessuna ragione tecnica per cui CharStream
non possa esistere.
Se vuoi una giustificazione, di solito devi girare la mailing list di OpenJDK. La documentazione del JDK non ha l'abitudine di giustificare perché* qualcosa è perché è.
Qualcuno ha chiesto
Usare IntStream per rappresentare il flusso di 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 la pena un altro 100K+ di impronta JDK ciascuno per questi moduli che non sono usati quasi mai. E se li aggiungessimo, qualcuno chiederebbe short, float, o boolean.
Detto altrimenti, se la gente insistesse per avere tutte le primitive specializzazioni, non avremmo specializzazioni primitive. Il che sarebbe peggio dello status quo.
Dice anche lo stesso altrove
Se volete trattarli come chars, potete downcastarli in chars abbastanza facilmente. Non sembra un caso d'uso abbastanza importante da avere un intero 'altro set di flussi. (Lo stesso vale per Short, Byte, Float).
**TL;DR: Non vale il costo di manutenzione.
*Nel caso siate curiosi, la query di google che ho usato era
site:http://mail.openjdk.java.net/ charstream
Come ha detto Eran, non è l'unico che manca.
Un BooleanStream
sarebbe inutile, un ByteStream
(se esistesse) può essere gestito come un InputStream
o convertito in IntStream
(come può essere short
), e float
può essere gestito come un DoubleStream
.
Poiché char
non è comunque in grado di rappresentare tutti i caratteri (vedi linked), sarebbe un bit di uno stream legacy. Anche se la maggior parte delle persone non ha comunque a che fare con i codepoints, quindi può sembrare strano. Voglio dire che si usa String.charAt()
senza pensare "questo non'funziona effettivamente in tutti i casi".
Quindi alcune cose sono state lasciate fuori 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 dai loro più grandi equivalenti (int, double) senza alcuna penalità significativa in termini di prestazioni.
La ragione per cui BooleanStream
sarebbe inutile, è perché hai solo 2 valori e questo limita molto le operazioni. Non ci sono operazioni matematiche da fare, e quanto spesso si lavora con molti valori booleani comunque?
Non sono solo gli array di "char" a non essere supportati.
Ci sono solo 3 tipi di flussi primitivi - IntStream
, LongStream
e DoubleStream
.
Di conseguenza, Arrays
ha metodi che convertono int[]
, long[]
e double[]
nei corrispondenti flussi primitivi.
Non ci sono metodi corrispondenti per boolean[]
, byte[]
, short[]
, char[]
e float[]
, poiché questi tipi primitivi non hanno flussi primitivi corrispondenti.
char
è una parte dipendente di String
- memorizzazione dei valori UTF-16. Un simbolo Unicode, un punto codice, è a volte una coppia surrogata di char. Quindi qualsiasi soluzione semplice con i caratteri copre solo una parte del dominio Unicode.
C'è stato un tempo in cui char
aveva il diritto di essere un tipo pubblico. Ma oggi è meglio usare punti di codice, un IntStream
. Un flusso di char non può gestire direttamente le coppie di surrogati.
L'altra ragione più prosaica è che il modello JVM "processor" utilizza un int
come "registro" più piccolo, mantenendo booleani, byte, shorts e anche char in una posizione di memorizzazione di tali dimensioni int. Per non gonfiare necessariamente le classi java, ci si è astenuti da tutte le possibili varianti di copia.
Nel lontano futuro ci si potrebbe aspettare che i tipi primitivi possano funzionare come parametri di tipo generico, fornendo una Lista<int>
. Poi potremmo vedere un Stream<char>
.
Per il momento è meglio evitare il char
, e magari usare il java.text.Normalizer
per una forma canonica unica di punti di codice / stringhe Unicode.