1. Introduction
It’s common to need to convert various dynamic data structures into arrays.
In this tutorial, we’ll demonstrate how to convert a Stream to an array and vice versa in Java.
2. Converting a Stream to an Array
2.1. Method Reference
*The best way to convert a Stream into an array is to use Stream’s toArray() method:*
public String[] usingMethodReference(Stream<String> stringStream) {
return stringStream.toArray(String[]::new);
}
Now, we can easily test if the conversion was successful:
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
assertArrayEquals(new String[] { "baeldung", "convert", "to", "string", "array" },
usingMethodReference(stringStream));
2.2. Lambda Expression
Another equivalent is to pass a lambda expression to the toArray() method:
public static String[] usingLambda(Stream<String> stringStream) {
return stringStream.toArray(size -> new String[size]);
}
This would give us the same result as with using the method reference.
2.3. Custom Class
Or, we can go all out and create a full-blown class.
As we can see from the Stream documentation, it takes an IntFunction as an argument. It takes the array size as input and returns an array of that size.
Of course, IntFunction is an interface so we can implement it:
class MyArrayFunction implements IntFunction<String[]> {
@Override
public String[] apply(int size) {
return new String[size];
}
};
We can then construct and use as normal:
public String[] usingCustomClass(Stream<String> stringStream) {
return stringStream.toArray(new MyArrayFunction());
}
Consequently, we can make the same assertion as earlier.
2.4. Primitive Arrays
In the previous sections, we explored how to convert a String Stream to a String array. In fact, we can perform the conversion this way for any Object and it would look very similar to the String examples above.
It’s a bit different for primitives, though. If we have a Stream of Integers that we want to convert to int[], for example, we first need to call the mapToInt() method:
public int[] intStreamToPrimitiveIntArray(Stream<Integer> integerStream) {
return integerStream.mapToInt(i -> i).toArray();
}
There’s also mapToLong() and mapToDouble() methods at our disposal. Also, please note that we didn’t pass any argument to the toArray() this time.
Finally, let’s do the equality assertion and confirm that we’ve got our int array correctly:
Stream<Integer> integerStream = IntStream.rangeClosed(1, 7).boxed();
assertArrayEquals(new int[]{1, 2, 3, 4, 5, 6, 7}, intStreamToPrimitiveIntArray(integerStream));
What if we need to do the opposite, though? Let’s take a look.
3. Converting an Array to a Stream
We can, of course, go the other way, too. And Java has some dedicated methods for that.
3.1. Array of Objects
We can convert the array to a Stream using Arrays.stream() or Stream.of() methods:
public Stream<String> stringArrayToStreamUsingArraysStream(String[] stringArray) {
return Arrays.stream(stringArray);
}
public Stream<String> stringArrayToStreamUsingStreamOf(String[] stringArray) {
return Stream.of(stringArray);
}
We should note that in both cases, our Stream is of the same time as our array.
3.2. Array of Primitives
Similarly, we can convert an array of primitives:
public IntStream primitiveIntArrayToStreamUsingArraysStream(int[] intArray) {
return Arrays.stream(intArray);
}
public Stream<int[]> primitiveIntArrayToStreamUsingStreamOf(int[] intArray) {
return Stream.of(intArray);
}
But, in contrast to converting Objects arrays, there is an important difference. *When converting primitives array, Arrays.stream() returns IntStream, while Stream.of() returns Stream<int[]>.*
3.3. Arrays.stream vs. Stream.of
In order to understand the differences mentioned in earlier sections, we’ll take a look at the implementation of the corresponding methods.
Let’s first take a peek at Java’s implementation of these two methods:
public <T> Stream<T> stream(T[] array) {
return stream(array, 0, array.length);
}
public <T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
We can see that Stream.of() is actually calling Arrays.stream() internally and that’s obviously the reason why we get the same results.
Now, we’ll check out the methods in the case when we want to convert an array of primitives:
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);
}
This time, Stream.of() is not calling the Arrays.stream().
4. Conclusion
In this article, we saw how we can convert Streams to arrays in Java and the other way round. We also explained why we get different results when converting an array of Objects and when we use an array of primitives.
As always, complete source code can be found over on GitHub.