如何使用Java 8 Stream映射和收集原始返回类型

glf*_*f4k 4 java arrays byte java-8 java-stream

我是Java 8流的新手,我想知道是否有方法执行forEach/map调用方法返回a byte并接受intas参数.

例:

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[]
   }
}
Run Code Online (Sandbox Code Playgroud)

你可能猜到,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;
Run Code Online (Sandbox Code Playgroud)

Don*_*aab 5

如果您愿意使用第三方库,那么Eclipse Collections可以为所有八种Java基元类型提供集合支持.以下应该有效:

public byte[] getBytes(int... indexes) {
    return IntLists.mutable.with(indexes)
            .asLazy()
            .collectByte(this::getByte)
            .toArray();
}
Run Code Online (Sandbox Code Playgroud)

更新:我将原始代码更改为懒惰.

注意:我是Eclipse Collections的提交者


Flo*_*own 5

您可以编写自己的代码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);
  }
}
Run Code Online (Sandbox Code Playgroud)

并使用它:

public byte[] getBytes(int... indexes) {
  return IntStream.of(indexes).mapToObj(this::getByte).collect(MyCollectors.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)