Beim Durchgehen durch die Möglichkeiten der Umwandlung von primitiven Arrays in Streams, fand ich, dass char[]
nicht unterstützt werden, während andere primitive Array-Typen unterstützt werden. Gibt es einen besonderen Grund, sie im Stream auszulassen?
Die Antwort lautet natürlich: weil die Designer das so beschlossen haben". Es gibt keinen technischen Grund, warum CharStream
nicht existieren könnte.
Wenn Sie eine Begründung wollen, müssen Sie sich normalerweise an die OpenJDK Mailingliste wenden. Die JDK-Dokumentation hat nicht die Angewohnheit, zu begründen, warum* etwas so ist, wie es ist.
Jemand fragte
IntStream zu verwenden, um char/byte stream zu repräsentieren ist ein wenig
unpraktisch. Sollten wir CharStream und ByteStream ebenfalls hinzufügen?
Die Antwort von Brian Goetz (Java Language Architect) lautet
Kurze Antwort: nein.
Es lohnt sich nicht, weitere 100K+ JDK-Footprint für diese Formulare die fast nie verwendet werden. Und wenn wir diese hinzufügen würden, würde jemand short, float oder boolean verlangen.
Anders ausgedrückt: Wenn die Leute darauf bestünden, dass wir alle primitiven Spezialisierungen zu haben, würden wir keine primitiven Spezialisierungen haben. Das wäre schlimmer als der Status quo.
Das Gleiche sagt er auch an anderer Stelle
Wenn man sie als Zeichen behandeln will, kann man sie leicht zu
chars leicht genug. Doesn't seem like an important enough use case um eine ganze 'andere Reihe von Streams haben. (Dasselbe gilt für Short, Byte, Float).
TL;DR: Die Wartungskosten sind es nicht wert.
*Für den Fall, dass Sie neugierig sind, die Google-Abfrage, die ich verwendet habe, war
site:http://mail.openjdk.java.net/ charstream
Wie Eran sagte, ist das nicht das einzige, was fehlt.
Ein BooleanStream
wäre nutzlos, ein ByteStream
(wenn es ihn gäbe) kann als InputStream
behandelt oder in einen IntStream
umgewandelt werden (ebenso wie short
), und float
kann als DoubleStream
behandelt werden.
Da char
sowieso nicht alle Zeichen darstellen kann (siehe linked), wäre es ein Bit eines Legacy-Streams. Obwohl die meisten Leute sowieso nicht mit Codepoints zu tun haben, kann es also seltsam erscheinen. Ich meine, man benutzt String.charAt()
ohne zu denken "das funktioniert'nicht wirklich in allen Fällen".
Also wurden einige Dinge weggelassen, weil sie als nicht so wichtig erachtet wurden. Wie von JB Nizet in der [verlinkten Frage] (https://stackoverflow.com/questions/22435833/why-is-string-chars-a-stream-of-ints-in-java-8) gesagt:
Die Designer haben sich ausdrücklich dafür entschieden, die Explosion von Klassen und Methoden zu vermeiden.
Methoden zu vermeiden, indem sie die primitiven Ströme auf 3 Typen beschränkten, da die anderen Typen (char, short, float) durch ihre größeren Äquivalent (int, double) ohne nennenswerte Leistungseinbußen dargestellt werden können.
Der Grund, warum BooleanStream
nutzlos wäre, ist, dass man nur 2 Werte hat und das schränkt die Operationen sehr ein. Es gibt keine mathematischen Operationen zu tun, und wie oft arbeitet man sowieso mit vielen booleschen Werten?
Es werden nicht nur char
-Arrays nicht unterstützt.
Es gibt nur 3 Arten von primitiven Strömen - IntStream
, LongStream
und DoubleStream
.
Daher hat Arrays
Methoden, die int[]
, long[]
und double[]
in die entsprechenden primitiven Streams konvertieren.
Es gibt keine entsprechenden Methoden für boolean[]
, byte[]
, short[]
, char[]
und float[]
, da diese primitiven Typen keine entsprechenden primitiven Streams haben.
char
ist ein abhängiger Teil von String
- der UTF-16-Werte speichert. Ein Unicode-Symbol, ein Codepoint, ist manchmal ein Surrogat-Paar von Zeichen. Daher deckt jede einfache Lösung mit Zeichen nur einen Teil der Unicode-Domäne ab.
Es gab eine Zeit, da hatte Zeichen
sein eigenes Recht, ein öffentlicher Typ zu sein. Aber heutzutage ist es besser, Codestellen zu verwenden, einen IntStream
. Ein Strom von Zeichen könnte nicht ohne weiteres mit Surrogatpaaren umgehen.
Der andere, eher prosaische Grund ist, dass das JVM-"Prozessor"-Modell einen int
als kleinstes "Register" verwendet, das Booleans, Bytes, Shorts und auch Zeichen in einem solchen int-Speicherort aufbewahrt. Um die Java-Klassen nicht unbedingt aufzublähen, verzichtete man auf alle möglichen Kopiervarianten.
In der fernen Zukunft könnte man primitive Typen erwarten, die als generische Typparameter fungieren und eine Liste<int>
bereitstellen. Dann könnten wir ein Stream<char>
sehen.
Im Moment ist es besser, Zeichen
zu vermeiden und vielleicht Java.text.Normalizer
für eine eindeutige kanonische Form von Codepoints / Unicode-Strings zu verwenden.