我是Java 8流的新手,我想知道是否有办法forEach/map
调用方法返回byte
并接受int
作为参数。
示例:
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[]
}
}
正如您可能猜到的那样,getBytes
方法无效。 "int[] cannot be converted to int"
可能某个地方缺少预告,但个人无法弄明白。
然而,这是一种有效的,老式的方法,我想将其重写为Stream。
byte[] byteArray = new byte[indexes.length];
for ( int i = 0; i < byteArray.length; i++ ) {
byteArray[i] = this.getByte( indexes[i] );
}
return byteArray;
答案 0 :(得分:5)
如果您愿意使用第三方库,Eclipse Collections对所有八种Java基元类型都有集合支持。以下应该有效:
public byte[] getBytes(int... indexes) {
return IntLists.mutable.with(indexes)
.asLazy()
.collectByte(this::getByte)
.toArray();
}
更新:我将原始代码更改为懒惰。
注意:我是Eclipse Collections的提交者
答案 1 :(得分:4)
您可以编写自己的Collector
并使用byte[]
构建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);
}
}
并使用它:
public byte[] getBytes(int... indexes) {
return IntStream.of(indexes).mapToObj(this::getByte).collect(MyCollectors.toByteArray());
}
答案 2 :(得分:3)
用流来做这个没有好办法。使用collect
的任何实现都将依赖于附加元素,这对于数组来说非常难看。这就像你要获得的那样接近:
int[] ints = IntStream.of(indexes)
.map(this::getByte) // upcast to int, still IntStream
.toArray(); // specialized collect
IntStream.toArray
方法有大量的开销涉及内部&#34;节点&#34;对象和数组连接,因此效率也低得多。我建议坚持使用旧的for
循环。