Java 8はStream<T>
double
、int
、long
の特殊化:DoubleStream
、IntStream
、LongStream
。しかし、 ドキュメント でbyte
に相当するものが見つかりませんでした。
Java 8はByteStream
クラスを提供しますか?
いいえ、存在しません。実際には、すべてのプリミティブ型の大量のクラスでStream APIが乱雑にならないように、明示的に実装されていません。
a mail OpenJDKメーリングリストのBrian Goetzからの引用:
短い答え:いいえ。
これらのフォームに使用されるJDKフットプリントは、ほとんど使用されることはないため、別の100K以上のフットプリントには値しません。そして、それらを追加すると、誰かがshort、float、またはbooleanを要求します。
別の言い方をすれば、人々が私たちにすべての原始的な専門化があると主張した場合、原始的な専門化はないでしょう。これは現状よりも悪いでしょう。
バイト関連の操作のほとんどは、自動的にintに昇格されます。たとえば、新しい_byte[]
_配列(byte
の潜在的な候補)を返す_byte[]
_配列の各要素にByteStream
定数を追加する簡単な方法を考えてみましょう。
_public static byte[] add(byte[] arr, byte addend) {
byte[] result = new byte[arr.length];
int i=0;
for(byte b : arr) {
result[i++] = (byte) (b+addend);
}
return result;
}
_
2つのbyte
変数の追加を実行しても、それらはint
に拡張されるため、結果をbyte
にキャストする必要があります。 Javaバイトコードbyte
関連操作のほとんど(配列のロード/ストアおよびバイトへのキャストを除く)は、32ビット整数命令(iadd
、 ixor
、_if_icmple
_など)。したがって、IntStream
を使用してintとしてバイトを処理することは実際には問題ありません。
byte[]
_配列からIntStream
を作成(バイトをintに拡張)IntStream
を_byte[]
_配列に収集します(_(byte)
_キャストを使用)最初のものは本当に簡単で、次のように実装できます。
_public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
_
そのため、このような静的メソッドをプロジェクトに追加して、満足することができます。
ストリームを_byte[]
_配列に収集することは、より注意が必要です。標準のJDKクラスを使用する最も簡単なソリューションはByteArrayOutputStream
です:
_public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i),
(baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
}
_
ただし、同期のために不要なオーバーヘッドがあります。また、割り当てとコピーを削減するために、既知の長さのストリームを特別に処理することは素晴らしいことです。それでも、今では_byte[]
_配列に対してStream APIを使用できます:
_public static byte[] addStream(byte[] arr, byte addend) {
return toByteArray(intStream(arr).map(b -> b+addend));
}
_
私の StreamEx ライブラリには、標準のIntStreamEx
を拡張する IntStream
クラスでこれらの操作の両方があるため、次のように使用できます。
_public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
_
内部的にtoByteArray()
メソッドは、単純なサイズ変更可能な byte buffer および 特別にハンドル を使用します。これは、ストリームがシーケンシャルで、ターゲットサイズが事前にわかっている場合です。