I am new in Java 8 streams and I am wondering if there is way to perform forEach/map
call on method returning a byte
and accepting an int
as parameter.
Example:
public class Test {
private byte[] byteArray; // example of byte array
public byte getByte(int index) {
return this.byteArray[index];
}
public byte[] getBytes(int... indexes) {
return Stream.of(indexes)
.map(this::getByte) // should return byte
.collect(byte[]::new); // should return byte[]
}
}
As you may guess, the getBytes
method not working. "int[] cannot be converted to int"
Probably somewhere is missing foreach, but personally cant figure it out.
However, this is working, old-fashioned approach which I would like to rewrite as Stream.
byte[] byteArray = new byte[indexes.length];
for ( int i = 0; i < byteArray.length; i++ ) {
byteArray[i] = this.getByte( indexes[i] );
}
return byteArray;
You can write your own Collector
and build your byte[]
with an ByteArrayOutputStream
:
final class MyCollectors {
private MyCollectors() {}
public static Collector<Byte, ?, byte[]> toByteArray() {
return Collector.of(ByteArrayOutputStream::new, ByteArrayOutputStream::write, (baos1, baos2) -> {
try {
baos2.writeTo(baos1);
return baos1;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}, ByteArrayOutputStream::toByteArray);
}
}
And use it:
public byte[] getBytes(int... indexes) {
return IntStream.of(indexes).mapToObj(this::getByte).collect(MyCollectors.toByteArray());
}
If you are open to using a third-party library, Eclipse Collections has collections support for all eight Java primitive types. The following should work:
public byte[] getBytes(int... indexes) {
return IntLists.mutable.with(indexes)
.asLazy()
.collectByte(this::getByte)
.toArray();
}
Updated: I changed the original code to be lazy.
Note: I am a committer for Eclipse Collections
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