[英]How to map and collect primitive return type using Java 8 Stream
我是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"
可能某个地方缺少foreach,但个人无法弄明白。
然而,这是一种工作,老式的方法,我想重写为Stream。
byte[] byteArray = new byte[indexes.length];
for ( int i = 0; i < byteArray.length; i++ ) {
byteArray[i] = this.getByte( indexes[i] );
}
return byteArray;
如果您愿意使用第三方库,那么Eclipse Collections可以为所有八种Java基元类型提供集合支持。 以下应该有效:
public byte[] getBytes(int... indexes) {
return IntLists.mutable.with(indexes)
.asLazy()
.collectByte(this::getByte)
.toArray();
}
更新:我将原始代码更改为懒惰。
注意:我是Eclipse Collections的提交者
您可以编写自己的Collector
并使用ByteArrayOutputStream
构建byte[]
:
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());
}
用流做这个没有好办法。 使用collect
任何实现都将依赖于附加元素,这对于数组来说非常难看。 这就像你将得到的那样接近:
int[] ints = IntStream.of(indexes)
.map(this::getByte) // upcast to int, still IntStream
.toArray(); // specialized collect
IntStream.toArray
方法有大量的开销涉及内部“节点”对象和数组连接,因此效率也低得多。 我建议坚持旧的for
循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.