Java 8 has java.util.stream.Stream and java.util.stream.IntStream types. java.util.Arrays has a method
IntStream is = Arrays.stream(int[])
but no such method to make an IntStream from a byte[], short[] or char[], widening each element to an int. Is there an idiomatic/preferred way to create an IntStream from a byte[], so I can operate on byte arrays in a functional manner?
I can of course trivially convert the byte[] to int[] manually and use Arrays.stream(int[]), or use IntStream.Builder:
public static IntStream stream(byte[] bytes) {
IntStream.Builder isb = IntStream.builder();
for (byte b: bytes)
isb.add((int) b);
return isb.build();
}
but neither is very functional due to the copying of the source.
There also does not seem to be an easy way to convert an InputStream (or in this case an ByteArrayInputStream) to an IntStream, which would be very useful for processing InputStream functionally. (Glaring omission?)
Is there a more functional way that is efficient and does not copy?
Write the contents of the object to the output stream using the writeObject() method of the ObjectOutputStream class. Flush the contents to the stream using the flush() method. Finally, convert the contents of the ByteArrayOutputStream to a byte array using the toByteArray() method.
The process of converting a byte array to a String is called decoding.
An IntStream interface extends the BaseStream interface in Java 8. It is a sequence of primitive int-value elements and a specialized stream for manipulating int values. We can also use the IntStream interface to iterate the elements of a collection in lambda expressions and method references.
byte[] bytes = {2, 6, -2, 1, 7};
IntStream is = IntStream.range(0, bytes.length).map(i -> bytes[i]);
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
IntStream is2 = IntStream.generate(inputStream::read).limit(inputStream.available());
public static IntStream stream(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
return IntStream.generate(buffer::get).limit(buffer.remaining());
}
(This can easily be changed to take int
s from the ByteBuffer
, ie. 4 bytes to the int
.)
For InputStream
, if you want to consume it eagerly, just read it into a byte[]
and use the above. If you want to consume it lazily, you could generate an infinite InputStream
using InputStream::read
as a Consumer
(plus exception handling) and end it when you've reached the end of the stream.
Concerning
but neither is very functional due to the copying of the source
I don't see why that makes it non functional.
Also relevant
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With