Проходя через способы преобразования примитивных массивов в потоки, я обнаружил, что char[]они не поддерживаются, в то время как поддерживаются другие типы примитивных массивов. Есть какая-то конкретная причина, чтобы оставить их в потоке?
Проходя через способы преобразования примитивных массивов в потоки, я обнаружил, что char[]они не поддерживаются, в то время как поддерживаются другие типы примитивных массивов. Есть какая-то конкретная причина, чтобы оставить их в потоке?
Ответы:
Как сказал Эран, это не единственный пропавший.
A BooleanStreamбудет бесполезным, a ByteStream(если он существует) может быть обработан как InputStreamили преобразован в IntStream(как может short), и floatможет быть обработан как DoubleStream.
Поскольку charв любом случае невозможно представить все символы (см. Ссылку), это будет немного устаревшим потоком. Хотя большинству людей в любом случае не приходится иметь дело с кодовыми точками, это может показаться странным. Я имею в виду, что вы используете, String.charAt()не думая, что «это не работает во всех случаях».
Поэтому некоторые вещи были опущены, потому что они не считались такими важными. Как сказал Дж. Б. Низет в связанном вопросе :
Разработчики явно решили избежать взрыва классов и методов, ограничив примитивные потоки тремя типами, поскольку другие типы (char, short, float) могут быть представлены их большим эквивалентом (int, double) без какого-либо существенного снижения производительности.
Причина BooleanStreamбудет бесполезной, потому что у вас есть только 2 значения, и это сильно ограничивает операции. Там нет математических операций, и как часто вы работаете с большим количеством логических значений в любом случае?
BooleanStreamбыло бы бесполезно»: почему?
reduce(Boolean::logicalAnd)или reduce(Boolean::logicalOr), на boolean[]? В конце концов, методы logicalAndи logicalOrбыли добавлены в Java 8, так что я могу выполнять эти операции сокращения a Stream<Boolean>... Кстати, вы можете выполнять потоковую передачу по char[]так легко CharBuffer.wrap(array).chars()или CharBuffer.wrap(array).codePoints(), в зависимости от того, какую семантику вы предпочитаете.
Boolean::logicalAnd, что существует, он не обязательно гарантирует существование BooleanStream. В конце концов, они могут быть использованы в лямбда-ситуациях, не связанных с потоком. Я могу представить, что кто-то захочет это сделать reduce(Boolean::logicalAnd), но никому не нужно это делать.
while (i < limit), но ни в коем случае никому не нужно делать это [с использованием инструкций по сборке веток и переходов]»
<Primitive>Streamпримитивов, заключается в том, что они слишком сильно раздувают API. Правильный вопрос, который нужно задать, это "почему IntStreamвообще?" и неудачный ответ заключается в том, что система типов Java не достаточно понятна, чтобы выразить ее Stream<int>без потери производительности при использовании Integer. Если Java были типов значений, которые могут быть выделены в стеке или встраивать непосредственно в линии внутри других структур данных, то не было бы такой необходимости что - либо , кромеStream<T>
Конечно, ответ « потому что так решили дизайнеры ». Нет технической причины, по которой CharStreamне могло существовать.
Если вы хотите оправдания, вам обычно нужно включить список рассылки OpenJDK *. Документация JDK не имеет привычки обосновывать, почему что-то есть, почему это так.
Кто-то спросил
Использование IntStream для представления потока символов / байтов немного неудобно. Должны ли мы также добавить CharStream и ByteStream?
В ответе Брайана Гетца (Java Language Architect) говорится:
Краткий ответ: нет.
Для этих форм, которые используются почти никогда, не стоит больше 100K + JDK. И если бы мы добавили их, кто-то потребовал бы short, float или boolean.
Иными словами, если бы люди настаивали на том, что у нас были все примитивные специализации, у нас не было бы примитивных специализаций. Что было бы хуже, чем статус-кво.
Он также говорит то же самое в другом месте
Если вы хотите обращаться с ними как с символами, вы можете достаточно легко превратить их в символы. Не кажется достаточно важным вариантом использования, чтобы иметь целый «другой набор потоков». (То же самое с Short, Byte, Float).
TL; DR: не стоит затрат на обслуживание.
* Если вам интересно, я использовал запрос Google:
site:http://mail.openjdk.java.net/ charstream
100K+ of JDK footprint?
Это не только charмассивы, которые не поддерживаются.
Есть только три типа примитивных потоков - IntStream, LongStreamи DoubleStream.
В результате Arraysимеют методы , которые преобразуют int[], long[]и double[]к соответствующим примитивным потокам.
Там нет соответствующих методов boolean[], byte[], short[], char[]и float[], так как эти примитивные типов имеют соответствующие примитивные потоки.
charявляется зависимой частью Stringхранения значений UTF-16. Символ Unicode, кодовая точка , иногда является суррогатной парой символов. Таким образом, любое простое решение с символами покрывает только часть домена Unicode.
Было время, которое charимело собственное право быть публичным типом. Но в наше время, лучше использовать кодовые точки , IntStream. Поток полукокса не может напрямую обрабатывать суррогатные пары.
Другая более прозаическая причина заключается в том, что модель «процессора» JVM использует intнаименьший «регистр», сохраняя логические значения, байты, шорты, а также символы в таком месте хранения int. Чтобы не обязательно раздувать Java-классы, нужно воздерживаться от всех возможных вариантов копирования.
В далеком будущем можно ожидать, что примитивные типы могут функционировать как параметры универсального типа, обеспечивая a List<int>. Тогда мы можем увидеть Stream<char>.
На данный момент лучше избегать charи, возможно, использовать java.text.Normalizerдля уникальной канонической формы кодовые точки / строки Unicode.