1. Overview

Working with arrays and streams is a common task in Java, particularly when dealing with complex data structures. While 1D arrays and streams are straightforward, converting between 2D arrays and streams can be more involved.

In this tutorial, we’ll walk through converting a 2D array to a stream and vice versa, with detailed explanations and practical examples.

2. Converting a Two-Dimensional Array to a Stream

We’ll discuss two ways to solve this problem. The first is converting it to a stream of rows and the second one is to convert it to flat streams.

2.1. Convert a 2D Array to a Stream of Rows

To convert a 2D array to a stream of its rows, we can use the Arrays.stream() method.

Let’s see the respective test case:

int[][] array2D = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

Stream<int[]> streamOfRows = Arrays.stream(array2D);
int[][] resultArray2D = streamOfRows.toArray(int[][]::new);

assertArrayEquals(array2D, resultArray2D);

This creates a Stream<int[]> where each element in the stream is an array representing a row of the original 2D array.

2.2. Convert to a Flat Stream

If we want to flatten the 2D array into a single stream of elements, we can use the flatMapToInt() method.

Let’s see a test case showing how to implement it:

int[][] array2D = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

IntStream flatStream = Arrays.stream(array2D) 
  .flatMapToInt(Arrays::stream);
int[] resultFlatArray = flatStream.toArray();

int[] expectedFlatArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

assertArrayEquals(expectedFlatArray, resultFlatArray);

This method takes a function that maps each row (array) to an IntStream, and then flattens these streams into a single IntStream.

3. Converting a Stream to a Two-Dimensional Array

Let’s look at two ways to convert a stream to a 2D array.

3.1. Convert a Stream of Rows to a 2D Array

To convert a stream of rows (arrays) back into a 2D array, we can use the Stream.toArray() method. We must provide an array generator function that creates a 2D array of the required type.

Let’s see how it can be done:

int[][] originalArray2D = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

Stream<int[]> streamOfRows = Arrays.stream(originalArray2D);
int[][] resultArray2D = streamOfRows.toArray(int[][]::new);

assertArrayEquals(originalArray2D, resultArray2D);

This way we easily converted the stream to the 2D array.

3.2. Convert a Flat Stream to a 2D Array

If we have a flat stream of elements and want to convert it into a 2D array, we need to know the dimensions of the target array. We can first collect the stream into a flat array and then populate the 2D array accordingly.

Let’s see how:

int[] flatArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

IntStream flatStream = Arrays.stream(flatArray);
int rows = 3;
int cols = 3;

int[][] expectedArray2D = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[][] resultArray2D = new int[rows][cols];
int[] collectedArray = flatStream.toArray();

for (int i = 0; i < rows; i++) {
    System.arraycopy(collectedArray, i * cols, resultArray2D[i], 0, cols);
}

assertArrayEquals(expectedArray2D, resultArray2D);

As a result, we’ll get our resultant 2D array.

4. Conclusion

In this article, we saw that converting between 2D arrays and streams in Java is a valuable skill that can simplify many programming tasks, especially when dealing with large datasets or performing complex transformations.

By understanding how to effectively convert a 2D array to a stream of rows or a flat stream, and then reassemble them back into a 2D array, we can leverage the full power of Java’s Stream API for more efficient and readable code. The provided examples and unit tests serve as a practical guide to help us master these conversions, ensuring our code remains clean and maintainable.

As always, the source code of all these examples is available over on GitHub.