简体   繁体   中英

Stream from two dimensional array in java

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.

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.

To further expand on Rohit's answer, a method reference can be used to slightly shorten the amount of code required:

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

IntStream stream = Arrays.stream(arr).flatMapToInt(Arrays::stream);

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 + " "));
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM