Mientras revisaba las formas de convertir matrices primitivas en Streams, descubrí que char[]
no son compatibles mientras que otros tipos de matrices primitivas son compatibles. ¿Alguna razón en particular para dejarlos fuera de la corriente?
Mientras revisaba las formas de convertir matrices primitivas en Streams, descubrí que char[]
no son compatibles mientras que otros tipos de matrices primitivas son compatibles. ¿Alguna razón en particular para dejarlos fuera de la corriente?
Respuestas:
Como dijo Eran, no es el único que falta.
A BooleanStream
sería inútil, a ByteStream
(si existiera) puede manejarse como InputStream
o convertirse a IntStream
(como puede short
), y float
puede manejarse como a DoubleStream
.
Como char
no es capaz de representar todos los caracteres de todos modos (ver relacionado), sería un poco de una corriente legado. Aunque la mayoría de las personas no tienen que lidiar con puntos de código de todos modos, puede parecer extraño. Me refiero a que usas String.charAt()
sin pensar "esto en realidad no funciona en todos los casos".
Así que algunas cosas quedaron fuera porque no se consideraron tan importantes. Como dijo JB Nizet en la pregunta vinculada :
Los diseñadores decidieron explícitamente evitar la explosión de clases y métodos limitando las corrientes primitivas a 3 tipos, ya que los otros tipos (char, short, float) pueden representarse por su equivalente más grande (int, double) sin ninguna penalización de rendimiento significativa.
La razón BooleanStream
sería inútil, porque solo tiene 2 valores y eso limita mucho las operaciones. No hay operaciones matemáticas que hacer, y ¿con qué frecuencia está trabajando con muchos valores booleanos de todos modos?
BooleanStream
sería inútil": ¿por qué?
reduce(Boolean::logicalAnd)
o reduce(Boolean::logicalOr)
en un boolean[]
? Después de todo, los métodos logicalAnd
y logicalOr
se han añadido en Java 8, por lo que puedo hacer estas operaciones de reducción de un Stream<Boolean>
... Por cierto, se puede transmitir a través de una char[]
tan fácil como CharBuffer.wrap(array).chars()
o CharBuffer.wrap(array).codePoints()
, según el cual semántica lo prefiere.
Boolean::logicalAnd
existe, no necesariamente garantiza la existencia de a BooleanStream
. Esos pueden usarse en situaciones lambda que no son stream después de todo. Me imagino que alguien querría hacerlo reduce(Boolean::logicalAnd)
, pero en ningún caso nadie necesita hacerlo.
while (i < limit)
, pero en ningún caso alguien tiene que hacerlo [sobre el uso de las instrucciones de montaje de rama y salto]"
<Primitive>Stream
para cada tipo primitivo es porque hinchará demasiado la API. La pregunta correcta que debe hacerse es "¿por qué hay algo IntStream
?" y la desafortunada respuesta es porque el sistema de tipos de Java no está lo suficientemente desarrollado como para expresarse Stream<int>
sin todos los gastos de rendimiento del uso Integer
. Si Java tuviera tipos de valor, que podrían asignarse en la pila o incrustarse directamente en línea dentro de otras estructuras de datos, no habría tanta necesidad de nada además deStream<T>
Por supuesto, la respuesta es " porque eso es lo que decidieron los diseñadores ". No hay una razón técnica por la que CharStream
no pueda existir.
Si desea justificación, generalmente necesita activar la lista de correo de OpenJDK *. La documentación del JDK no tiene la costumbre de justificar por qué algo es por qué es.
Alguien pregunto
Usar IntStream para representar la secuencia char / byte es un poco inconveniente. ¿Deberíamos agregar CharStream y ByteStream también?
La respuesta de Brian Goetz (Java Language Architect) dice
Respuesta corta: no.
No vale más de 100K + de huella JDK cada uno para estos formularios que casi nunca se usan. Y si agregamos esos, alguien exigiría short, float o boolean.
Dicho de otra manera, si la gente insistiera en que teníamos todas las especializaciones primitivas, no tendríamos especializaciones primitivas. Lo cual sería peor que el status quo.
También dice lo mismo en otra parte.
Si desea tratarlos como caracteres, puede convertirlos en caracteres con la suficiente facilidad. No parece un caso de uso lo suficientemente importante como para tener un conjunto completo de transmisiones. (Lo mismo con Short, Byte, Float).
TL; DR: No vale la pena el costo de mantenimiento.
* En caso de que tenga curiosidad, la consulta de Google que utilicé fue
site:http://mail.openjdk.java.net/ charstream
100K+ of JDK footprint
?
No solo las char
matrices no son compatibles.
Solo hay 3 tipos de flujos primitivos IntStream
, LongStream
y DoubleStream
.
Como resultado, Arrays
tiene métodos que convierten int[]
, long[]
y double[]
a las corrientes primitivas correspondientes.
No existen métodos correspondientes para boolean[]
, byte[]
, short[]
, char[]
y float[]
, puesto que estos tipos primitivos no tienen correspondiente corrientes primitivas.
char
es una parte dependiente de String
- almacenar valores UTF-16. Un símbolo Unicode, un punto de código , a veces es un par de caracteres sustitutos. Por lo tanto, cualquier solución simple con caracteres solo cubre parte del dominio Unicode.
Hubo un tiempo que char
tenía su propio derecho a ser de tipo público. Pero hoy en día es mejor usar puntos de código , an IntStream
. Una corriente de char no podía manejar directamente pares sustitutos.
La otra razón más prosaica es que el modelo de "procesador" de JVM utiliza un int
"registro" más pequeño, manteniendo booleanos, bytes, cortos y también caracteres en una ubicación de almacenamiento de tamaño tan int. Para no necesariamente hinchar las clases de Java, uno se abstuvo de todas las posibles variantes de copia.
En el futuro lejano, uno podría esperar que los tipos primitivos funcionen como parámetros de tipo genérico, proporcionando a List<int>
. Entonces podríamos ver a Stream<char>
.
Por el momento, es mejor evitarlo char
y quizás usarlo java.text.Normalizer
para una forma canónica única de puntos de código / cadenas Unicode.