1. 序章

さまざまな動的データ構造配列変換する必要があるのが一般的です。

このチュートリアルでは、 Stream を配列に変換する方法、およびJavaでその逆を行う方法を示します。

2. Streamを配列に変換する

2.1. メソッドリファレンス

Stream を配列に変換する最良の方法は、 Stream’toArray()メソッドを使用することです。

public String[] usingMethodReference(Stream<String> stringStream) {
    return stringStream.toArray(String[]::new);
}

これで、変換が成功したかどうかを簡単にテストできます。

Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
assertArrayEquals(new String[] { "baeldung", "convert", "to", "string", "array" },
    usingMethodReference(stringStream));

2.2. ラムダ式

もう1つの同等の機能は、ラムダ式 toArray ()メソッドに渡すことです。

public static String[] usingLambda(Stream<String> stringStream) {
    return stringStream.toArray(size -> new String[size]);
}

これにより、メソッド参照を使用した場合と同じ結果が得られます。

2.3. カスタムクラス

または、すべてを行って本格的なクラスを作成することもできます。

ストリームドキュメントからわかるように、引数としてIntFunctionを取ります。 配列サイズを入力として受け取り、そのサイズの配列を返します。

もちろん、 IntFunction はインターフェースなので、次のように実装できます。

class MyArrayFunction implements IntFunction<String[]> {
    @Override
    public String[] apply(int size) {
        return new String[size];
    }
};

その後、通常どおりに構築して使用できます。

public String[] usingCustomClass(Stream<String> stringStream) {
    return stringStream.toArray(new MyArrayFunction());
}

したがって、以前と同じアサーションを作成できます。

2.4. プリミティブ配列

前のセクションでは、文字列ストリーム文字列配列に変換する方法について説明しました。 実際、この方法で任意の Object に対して変換を実行でき、上記のStringの例と非常によく似ています。

ただし、プリミティブの場合は少し異なります。 たとえば、 int[]に変換するIntegerStreamがある場合、最初に mapToInt( )メソッド:

public int[] intStreamToPrimitiveIntArray(Stream<Integer> integerStream) {
    return integerStream.mapToInt(i -> i).toArray();
}

mapToLong()および mapToDouble()メソッドも自由に使用できます。 また、今回は toArray()に引数を渡さなかったことに注意してください。

最後に、等式アサーションを実行して、int配列が正しく設定されていることを確認しましょう。

Stream<Integer> integerStream = IntStream.rangeClosed(1, 7).boxed();
assertArrayEquals(new int[]{1, 2, 3, 4, 5, 6, 7}, intStreamToPrimitiveIntArray(integerStream));

ただし、反対のことをする必要がある場合はどうなりますか? 見てみましょう。

3. 配列をStreamに変換する

もちろん、逆のこともできます。 そして、Javaにはそのための専用のメソッドがいくつかあります。

3.1. オブジェクトの配列

Arrays.stream()またはStream.of()メソッドを使用して配列をストリームに変換できます

public Stream<String> stringArrayToStreamUsingArraysStream(String[] stringArray) {
    return Arrays.stream(stringArray);
}

public Stream<String> stringArrayToStreamUsingStreamOf(String[] stringArray) {
    return Stream.of(stringArray);
}

どちらの場合も、Streamはアレイと同じ時間であることに注意してください。

3.2. プリミティブの配列

同様に、プリミティブの配列を変換できます。

public IntStream primitiveIntArrayToStreamUsingArraysStream(int[] intArray) {
    return Arrays.stream(intArray);
}

public Stream<int[]> primitiveIntArrayToStreamUsingStreamOf(int[] intArray) {
    return Stream.of(intArray);
}

ただし、 Object の配列を変換するのとは対照的に、重要な違いがあります。 プリミティブ配列を変換する場合、Arrays.stream()はIntStreamを返し、Stream.of()はStreamを返します。

3.3. Arrays.stream対。 Stream.of

前のセクションで説明した違いを理解するために、対応するメソッドの実装を見ていきます。

まず、Javaによるこれら2つのメソッドの実装を見てみましょう。

public <T> Stream<T> stream(T[] array) {
    return stream(array, 0, array.length);
}

public <T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

Stream.of()が実際に Arrays.stream()を内部的に呼び出していることがわかります。これが、同じ結果が得られる理由です。

ここで、プリミティブの配列を変換する場合のメソッドを確認します。

public IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

public <T> Stream<T> of(T t) {
    return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}

今回は、 Stream.of() Arrays.stream()を呼び出していません。

4. 結論

この記事では、StreamをJavaで配列に変換する方法とその逆の方法を説明しました。 また、 Object の配列を変換するときと、プリミティブの配列を使用するときに、異なる結果が得られる理由についても説明しました。

いつものように、完全なソースコードはGitHubにあります。