www whatwg spec language 3wc java java-8 byte java-stream boxing

whatwg - En Java 8, ¿hay una clase ByteStream?



w3c html standards (2)

La mayoría de las operaciones relacionadas con bytes se promueven automáticamente a int. Por ejemplo, consideremos el método simple que agrega una constante de byte a cada elemento de la matriz byte[] devuelve una nueva matriz byte[] (candidato potencial para ByteStream ):

public static byte[] add(byte[] arr, byte addend) { byte[] result = new byte[arr.length]; int i=0; for(byte b : arr) { result[i++] = (byte) (b+addend); } return result; }

Vea, a pesar de que realizamos una adición de dos variables de byte , se amplían a int y necesita convertir el resultado de nuevo a byte . En Java bytecode, la mayoría de las operaciones relacionadas con byte (excepto la carga / almacenamiento de if_icmple y la if_icmple a byte) se expresan con instrucciones de enteros de 32 bits ( iadd , ixor , if_icmple , etc.). Por lo tanto, prácticamente está bien procesar bytes como IntStream con IntStream . Solo necesitamos dos operaciones adicionales:

  • Cree un IntStream desde la IntStream de byte[] (ensanchando bytes a ints)
  • Recopile un IntStream en la IntStream de byte[] (usando el reparto (byte) )

El primero es realmente fácil y puede implementarse así:

public static IntStream intStream(byte[] array) { return IntStream.range(0, array.length).map(idx -> array[idx]); }

Entonces puede agregar un método estático a su proyecto y ser feliz.

Recopilar la secuencia en la matriz de byte[] es más complicado. Usando clases JDK estándar, la solución más simple es ByteArrayOutputStream :

public static byte[] toByteArray(IntStream stream) { return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i), (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size())) .toByteArray(); }

Sin embargo, tiene una sobrecarga innecesaria debido a la sincronización. También sería bueno procesar especialmente las secuencias de longitud conocida para reducir las asignaciones y la copia. Sin embargo, ahora puede usar la API Stream para conjuntos de byte[] :

public static byte[] addStream(byte[] arr, byte addend) { return toByteArray(intStream(arr).map(b -> b+addend)); }

Mi biblioteca StreamEx tiene ambas operaciones en la clase IntStreamEx que mejora IntStream estándar, por lo que puede usarlo así:

public static byte[] addStreamEx(byte[] arr, byte addend) { return IntStreamEx.of(arr).map(b -> b+addend).toByteArray(); }

Internamente, el método toByteArray() utiliza un búfer de bytes redimensionable simple y maneja especialmente el caso cuando la secuencia es secuencial y el tamaño objetivo se conoce de antemano.

Java 8 proporciona especializaciones Stream<T> para double , int y long : DoubleStream , IntStream y LongStream respectivamente. Sin embargo, no pude encontrar un equivalente para el byte en la documentación .

¿Java 8 proporciona una clase ByteStream ?


No, no existe. En realidad, no se implementó explícitamente para no saturar la API de Stream con toneladas de clases para cada tipo primitivo.

Citando un correo de Brian Goetz en la lista de correo de OpenJDK:

Respuesta corta: no.

No vale más de 100K + de huella JDK para cada uno de 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.