I am trying to get an IntStream out of an n dimensional int arrays. Is there a nice API way to do it?
I know the concatenate method for two streams.
4 Answers
Assuming you want to process array of array sequentially in row-major approach, this should work:
int[][] arr = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
IntStream stream = Arrays.stream(arr).flatMapToInt(x -> Arrays.stream(x));
First it invokes the Arrays.stream(T[]) method, where T is inferred as int[], to get a Stream<int[]>, and then Stream#flatMapToInt() method maps each int[] element to an IntStream using Arrays.stream(int[]) method.
3 Comments
IntStream traversing the array like 1, 2, 3, 4, 5, 6, ...?Function given to flatMapToInt takes each element in the int[][], ie. a single int[], and constructs and returns a new IntStream for each. All of these are concatenated into one final IntStream which is returned. (Not exactly, but that's how you can think of it.)To process the elements only, use flatMap as in Rohit's answer.
To process the elements with their indices, you may use IntStream.range as follows.
import java.util.stream.IntStream;
import static java.util.stream.IntStream.range;
public class StackOverflowTest {
public static void main(String... args) {
int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
// Map the two dimensional array with indices.
final IntStream intStream = range(0, arr.length).flatMap(row -> range(0, arr[row].length).map(col -> {
final int element = arr[row][col];
// E.g. multiply elements in odd numbered rows and columns by two.
return row % 2 == 1 || col % 2 == 1 ? element * 2 : element;
}));
// Prints "1 4 3 8 10 12 7 16 9 ".
intStream.forEachOrdered(n -> System.out.print(n + " "));
}
}
Comments
Adding to the previous answers, the method Arrays::stream returns a sequential stream
(see: Oracle Javadoc). In some situations, a parallel stream might improve performance. To explicitly request a parallel stream, you first need to convert to a List via Arrays::asList, then call parallelStream() on the resulting List.
To calculate the sum of a two dimensional int array using a IntStream, you can use following code:
int[][] twoDimArray = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
IntStream intStream = Arrays.asList(twoDimArray)
.parallelStream() // "rows" in parallel
.flatMapToInt(Arrays::stream); // "columns" sequentially
int sum = intStream.sum(); // = 45
The Stream created for processing the outer layer (rows, first dimension) is now executing in parallel, while the Streams for the inner layer (columns, second dimension) are still sequential (using Arrays::stream mentioned above).
Depending on the size and structure of your array, you might see a performance increase by factor 4 (that's what I measured in my own tests) or none at all. If your calculations are time critical, it might be worth a try to use a parallel Stream.
IntStreamto be iterating over eachintin theint[][]?