Ao analisar as maneiras de converter matrizes primitivas em Streams, descobri que char[]
elas não são suportadas enquanto outros tipos de matrizes primitivas são suportadas. Algum motivo específico para deixá-los de fora no fluxo?
Ao analisar as maneiras de converter matrizes primitivas em Streams, descobri que char[]
elas não são suportadas enquanto outros tipos de matrizes primitivas são suportadas. Algum motivo específico para deixá-los de fora no fluxo?
Respostas:
Como Eran disse, não é o único que falta.
A BooleanStream
seria inútil, a ByteStream
(se existir) pode ser tratado como um InputStream
ou convertido em IntStream
(como pode short
) e float
pode ser tratado como um DoubleStream
.
Como char
não é capaz de representar todos os caracteres de qualquer maneira (veja o link), seria um pouco um fluxo herdado. Embora a maioria das pessoas não precise lidar com pontos de código de qualquer maneira, isso pode parecer estranho. Quero dizer, você usa String.charAt()
sem pensar "isso realmente não funciona em todos os casos".
Então, algumas coisas foram deixadas de fora porque não foram consideradas tão importantes. Como disse JB Nizet na pergunta vinculada :
Os designers escolheram explicitamente evitar a explosão de classes e métodos limitando os fluxos primitivos a 3 tipos, já que os outros tipos (char, short, float) podem ser representados por seu equivalente maior (int, double) sem nenhuma penalidade significativa no desempenho.
O motivo BooleanStream
seria inútil, porque você tem apenas 2 valores e isso limita muito as operações. Não há operações matemáticas a serem feitas, e com que frequência você trabalha com muitos valores booleanos?
BooleanStream
seria inútil": por quê?
reduce(Boolean::logicalAnd)
ou reduce(Boolean::logicalOr)
em um boolean[]
? Afinal, os métodos logicalAnd
e logicalOr
foram adicionados no Java 8, para que eu possa fazer essas operações de redução de um Stream<Boolean>
… Aliás, você pode transmitir por um char[]
tão fácil quanto CharBuffer.wrap(array).chars()
ou CharBuffer.wrap(array).codePoints()
, dependendo da semântica que preferir.
Boolean::logicalAnd
existe, não necessariamente garante a existência de um BooleanStream
. Afinal, eles podem ser usados em situações lambda sem fluxo. Eu posso imaginar que alguém iria querer fazer reduce(Boolean::logicalAnd)
, mas em nenhum caso qualquer necessidade de fazê-lo.
while (i < limit)
, mas em nenhum caso alguém precisa fazê-lo [usando instruções de montagem de ramificação e salto]"
<Primitive>Stream
tipo primitivo é porque ela inchará muito a API. A pergunta correta a ser feita é "por que existe IntStream
?" e a resposta infeliz é que o sistema de tipos do Java não é desenvolvido o suficiente para ser expresso Stream<int>
sem toda a despesa de desempenho do uso Integer
. Se o Java tivesse tipos de valor, que poderiam ser alocados na pilha ou incorporados diretamente em linha em outras estruturas de dados, não haveria essa necessidade de mais nadaStream<T>
Obviamente, a resposta é " porque é isso que os designers decidiram ". Não há razão técnica para CharStream
não existir.
Se você deseja justificativa, geralmente precisa virar a lista de discussão do OpenJDK *. A documentação do JDK não tem o hábito de justificar por que razão existe alguma coisa.
Alguém perguntou
Usar o IntStream para representar o fluxo de caracteres / bytes é um pouco inconveniente. Devemos adicionar também CharStream e ByteStream?
A resposta de Brian Goetz (Java Language Architect) diz
Resposta curta: não.
Não vale mais 100K + da pegada JDK cada um para esses formulários que são usados quase nunca. E se os adicionássemos, alguém exigiria short, float ou boolean.
Dito de outra forma, se as pessoas insistissem que tínhamos todas as especializações primitivas, não teríamos especializações primitivas. O que seria pior que o status quo.
Ele também diz o mesmo em outro lugar
Se você deseja lidar com eles como caracteres, você pode baixá-los para caracteres com bastante facilidade. Não parece ser um caso de uso suficientemente importante para ter um conjunto completo de fluxos. (Mesmo com curto, byte, flutuador).
TL; DR: Não vale o custo de manutenção.
* Caso você esteja curioso, a consulta do Google que usei foi
site:http://mail.openjdk.java.net/ charstream
100K+ of JDK footprint
?
Não são apenas as char
matrizes que não são suportadas.
Existem apenas 3 tipos de fluxos primitivos - IntStream
, LongStream
e DoubleStream
.
Como resultado, Arrays
tem métodos que convertem int[]
, long[]
e double[]
para os fluxos de primitivas correspondentes.
Não há métodos correspondentes para boolean[]
, byte[]
, short[]
, char[]
e float[]
, uma vez que estes tipos primitivos não têm fluxos primitivos correspondente.
char
é uma parte dependente do String
armazenamento de valores UTF-16. Às vezes , um símbolo Unicode, um ponto de código , é um par substituto de caracteres. Portanto, qualquer solução simples com caracteres cobre apenas parte do domínio Unicode.
Houve um tempo que char
tinha seu próprio direito de ser do tipo público. Mas hoje em dia é melhor usar pontos de código , um IntStream
. Um fluxo de caracteres não podia lidar diretamente com pares substitutos.
A outra razão mais prosaica é que o modelo de "processador" da JVM usa o int
menor "registro", mantendo booleanos, bytes, shorts e também caracteres em um local de armazenamento de tamanho int. Para não necessariamente inchar as classes java, uma se absteve de todas as variantes de cópia possíveis.
Em um futuro distante, pode-se esperar que tipos primitivos possam funcionar como parâmetros de tipo genérico, fornecendo a List<int>
. Então podemos ver a Stream<char>
.
Por enquanto, é melhor evitar char
e talvez usar java.text.Normalizer
para uma forma canônica exclusiva de pontos de código / seqüências de caracteres Unicode.