web-dev-qa-db-ja.com

Java 8、ByteStreamクラスはありますか?

Java 8はStream<T>doubleintlongの特殊化:DoubleStreamIntStreamLongStream。しかし、 ドキュメントbyteに相当するものが見つかりませんでした。

Java 8はByteStreamクラスを提供しますか?

35
sdgfsdh

いいえ、存在しません。実際には、すべてのプリミティブ型の大量のクラスでStream APIが乱雑にならないように、明示的に実装されていません。

a mail OpenJDKメーリングリストのBrian Goetzからの引用:

短い答え:いいえ。

これらのフォームに使用されるJDKフットプリントは、ほとんど使用されることはないため、別の100K以上のフットプリントには値しません。そして、それらを追加すると、誰かがshort、float、またはbooleanを要求します。

別の言い方をすれば、人々が私たちにすべての原始的な専門化があると主張した場合、原始的な専門化はないでしょう。これは現状よりも悪いでしょう。

32
Tunaki

バイト関連の操作のほとんどは、自動的に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ビット整数命令(iaddixor、_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 および 特別にハンドル を使用します。これは、ストリームがシーケンシャルで、ターゲットサイズが事前にわかっている場合です。

36
Tagir Valeev