javaarrayslambdajava-streamdeclarative-programming

How to sum the elements of two 2d arrays?


I'm trying to add the elements of two two-dimensional arrays with each other, by using the java stream API.
I managed the problem with a one-dimensional array, but I don't know how to proceed further with a two-dimensional array.

Here is the code to transform:

public static int[][] add(final int[][] m1, final int[][] m2) {
    int[][] e = new int[m2.length][m2[0].length];
    for (int i = 0; i < m1.length; i++) {
        for (int j = 0; j < m1[i].length; j++) {
            e[i][j] = m1[i][j] + m2[i][j];
        }
    }
    return e;
}

And this is the code which I wrote for the same purpose but only with a one-dimensional array:

public static int[] addOneDimension(final int[] a, final int b[]) {
    int[] c = IntStream.range(0, a.length)
            .map(i -> a[i] + b[i])
            .toArray();
    return c;
}

In particular, I don't know how to use the map() method on two-dimensional arrays.


Solution

  • This can be implemented using IntStream and its methods mapToObj to handle rows and map to handle elements in each row:

    static int[][] add(int[][] a, int [][] b) {
        return IntStream.range(0, a.length)
                        .mapToObj(i -> add(a[i], b[i])) // int[] is object
                        .toArray(int[][]::new);         // create new 2D array
    }
        
    static int[] add(int[] a, int[] b) {
        return IntStream.range(0, a.length)
                        .map(i -> a[i] + b[i])  // processing int operands
                        .toArray();             // IntStream.toArray() returns int[]
    }
    

    Test

    int[][] a = {
        {1, 2},
        {3, 4}
    };
    
    int[][] b = {
        {10, 20},
        {30, 40}
    };
    
    System.out.println("Sum of a + b = ");
    Arrays.stream(add(a, b))
          .map(Arrays::toString)
          .forEach(System.out::println);
    

    Output

    Sum of a + b = 
    [11, 22]
    [33, 44]
    

    Single-method implementation may be as follows:

    static int[][] add2D(int[][] a, int [][] b) {
        return IntStream
                .range(0, a.length)
                .mapToObj(i -> IntStream
                                .range(0, a[i].length)
                                .map(j -> a[i][j] + b[i][j])
                                .toArray()
                )
                .toArray(int[][]::new);
    }