Podczas przechodzenia przez sposoby konwersji tablic prymitywnych na Streams, znalazłem, że char[]
nie są obsługiwane, podczas gdy inne prymitywne typy tablic są obsługiwane. Jakiś szczególny powód, aby pominąć je w strumieniu?
Oczywiście, odpowiedź brzmi "bo tak'postanowili projektanci". Nie ma żadnego technicznego powodu, dla którego CharStream
nie mógłby istnieć.
Jeśli chcesz uzasadnienia, zazwyczaj musisz zwrócić się do listy mailingowej OpenJDK. Dokumentacja JDK's nie ma w zwyczaju uzasadniać dlaczego* cokolwiek jest tym, czym jest.
Ktoś zapytał
Używanie IntStream do reprezentowania strumienia char/byte jest trochę niewygodne. Czy powinniśmy dodać CharStream i ByteStream również?
Odpowiedź od Briana Goetza (Java Language Architect) mówi
Krótka odpowiedź: nie.
Nie jest to warte kolejnych 100K+ śladu JDK każdy dla tych formularzy które są używane prawie nigdy. A gdybyśmy je dodali, ktoś by zażądałby short, float, lub boolean.
Innymi słowy, gdyby ludzie nalegali, abyśmy mieli wszystkie prymitywne specjalizacje, nie mielibyśmy żadnych prymitywnych specjalizacji. Co byłoby gorsze niż status quo.
To samo mówi również w innym miejscu
Jeśli chcesz się nimi zajmować jako charami, możesz je dość łatwo wyrzucić do charów wystarczająco łatwo. Doesn't seem like an important enough use case aby mieć cały 'inny zestaw strumieni. (To samo z Short, Byte, Float).
**TL;DR: Nie warto ponosić kosztów utrzymania.
*W przypadku, gdy jesteś ciekawy, zapytanie google, którego użyłem to
site:http://mail.openjdk.java.net/ charstream
Jak powiedział Eran, nie jest to jedyny brakujący element.
A BooleanStream
byłby bezużyteczny, ByteStream
(gdyby istniał) może być obsługiwany jako InputStream
lub konwertowany do IntStream
(tak jak short
), a float
może być obsługiwany jako DoubleStream
.
Ponieważ char
nie jest w stanie reprezentować wszystkich znaków (patrz linked), byłby to bit legacy stream. Chociaż większość ludzi nie'ma do czynienia z punktami kodowymi tak czy inaczej, więc może to wydawać się dziwne. Mam na myśli to, że używasz String.charAt()
bez myślenia "to nie'faktycznie działa we wszystkich przypadkach".
Więc niektóre rzeczy zostały pominięte, ponieważ nie zostały uznane za tak ważne. Jak powiedział JB Nizet w linkowanym pytaniu:
Projektanci wyraźnie wybrali, aby uniknąć eksplozji klas i metod przez ograniczenie prymitywnych strumieni do 3 typów, ponieważ inne typy (char, short, float) mogą być reprezentowane przez ich większe odpowiedniki (int, double) bez znaczącej kary za wydajność.
Powodem, dla którego BooleanStream
byłby bezużyteczny, jest to, że masz tylko 2 wartości i to bardzo ogranicza operacje. Nie ma żadnych operacji matematycznych do wykonania, a jak często pracujesz z wieloma wartościami boolean?
Nie tylko tablice char
nie są obsługiwane.
Istnieją tylko 3 typy prymitywnych strumieni - IntStream
, LongStream
i DoubleStream
.
W rezultacie, Arrays
posiada metody, które konwertują int[]
, long[]
i double[]
do odpowiadających im prymitywnych strumieni.
Nie ma odpowiednich metod dla boolean[]
, byte[]
, short[]
, char[]
i float[]
, ponieważ te prymitywne typy nie mają odpowiadających im prymitywnych strumieni.
char
jest zależną częścią String
- przechowywania wartości UTF-16. Symbol Unicode, code point, jest czasem zastępczą parą znaków. Tak więc każde proste rozwiązanie ze znakami obejmuje tylko część domeny Unicode.
Był taki czas, że znak
miał swoje własne prawo do bycia typem publicznym. Ale teraz lepiej jest używać punktów kodu, IntStream
. Strumień znaków nie mógł w prosty sposób obsługiwać par zastępczych.
Innym, bardziej prozaicznym powodem jest to, że model "procesora" JVM używa int
jako najmniejszego "rejestru", trzymając booleany, bajty, szorty, a także znaki w tak zwartym miejscu przechowywania. Aby niekoniecznie wzdąć klasy java, powstrzymano się od wszelkich możliwych wariantów kopiowania.
W dalekiej przyszłości można się spodziewać, że typy prymitywne będą mogły funkcjonować jako parametry typu generycznego, dostarczając List<int>
. Wówczas możemy zobaczyć Stream<char>
.
Na razie lepiej unikać char
, a może użyć java.text.Normalizer
dla unikalnej kanonicznej formy punktów kodu / łańcuchów Unicode.