Java Program to Multiply Two Matrices
for loops to calculate the sum of products of corresponding elements, like result[i][j] += matrix1[i][k] * matrix2[k][j] inside three loops iterating over rows and columns.Examples
How to Think About It
Algorithm
Code
public class MatrixMultiplication { public static void main(String[] args) { int[][] matrix1 = {{1, 2}, {3, 4}}; int[][] matrix2 = {{5, 6}, {7, 8}}; int rows1 = matrix1.length; int cols1 = matrix1[0].length; int cols2 = matrix2[0].length; int[][] result = new int[rows1][cols2]; for (int i = 0; i < rows1; i++) { for (int j = 0; j < cols2; j++) { for (int k = 0; k < cols1; k++) { result[i][j] += matrix1[i][k] * matrix2[k][j]; } } } System.out.println("Result matrix:"); for (int[] row : result) { for (int val : row) { System.out.print(val + " "); } System.out.println(); } } }
Dry Run
Let's trace multiplying matrix1 = {{1, 2}, {3, 4}} and matrix2 = {{5, 6}, {7, 8}} through the code.
Initialize matrices and result
matrix1 = [[1, 2], [3, 4]], matrix2 = [[5, 6], [7, 8]], result = [[0, 0], [0, 0]]
Calculate result[0][0]
result[0][0] = (1*5) + (2*7) = 5 + 14 = 19
Calculate result[0][1]
result[0][1] = (1*6) + (2*8) = 6 + 16 = 22
Calculate result[1][0]
result[1][0] = (3*5) + (4*7) = 15 + 28 = 43
Calculate result[1][1]
result[1][1] = (3*6) + (4*8) = 18 + 32 = 50
| i | j | k | matrix1[i][k] | matrix2[k][j] | Partial sum for result[i][j] |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 5 | 5 |
| 0 | 0 | 1 | 2 | 7 | 19 |
| 0 | 1 | 0 | 1 | 6 | 6 |
| 0 | 1 | 1 | 2 | 8 | 22 |
| 1 | 0 | 0 | 3 | 5 | 15 |
| 1 | 0 | 1 | 4 | 7 | 43 |
| 1 | 1 | 0 | 3 | 6 | 18 |
| 1 | 1 | 1 | 4 | 8 | 50 |
Why This Works
Step 1: Matrix multiplication rule
Each element in the result matrix is the sum of products of elements from a row of the first matrix and a column of the second matrix using result[i][j] += matrix1[i][k] * matrix2[k][j].
Step 2: Nested loops for rows and columns
The outer two loops select the position i, j in the result matrix, and the inner loop sums the products over k.
Step 3: Result matrix size
The result matrix has the number of rows of the first matrix and the number of columns of the second matrix.
Alternative Approaches
public class MatrixMultiplication { public static int[][] multiply(int[][] m1, int[][] m2) { int rows1 = m1.length; int cols1 = m1[0].length; int cols2 = m2[0].length; int[][] res = new int[rows1][cols2]; for (int i = 0; i < rows1; i++) { for (int j = 0; j < cols2; j++) { for (int k = 0; k < cols1; k++) { res[i][j] += m1[i][k] * m2[k][j]; } } } return res; } public static void main(String[] args) { int[][] a = {{1, 2}, {3, 4}}; int[][] b = {{5, 6}, {7, 8}}; int[][] c = multiply(a, b); for (int[] row : c) { for (int val : row) System.out.print(val + " "); System.out.println(); } } }
import java.util.stream.IntStream; public class MatrixMultiplication { public static void main(String[] args) { int[][] m1 = {{1, 2}, {3, 4}}; int[][] m2 = {{5, 6}, {7, 8}}; int rows1 = m1.length; int cols2 = m2[0].length; int cols1 = m1[0].length; int[][] result = new int[rows1][cols2]; IntStream.range(0, rows1).forEach(i -> { IntStream.range(0, cols2).forEach(j -> { result[i][j] = IntStream.range(0, cols1) .map(k -> m1[i][k] * m2[k][j]) .sum(); }); }); for (int[] row : result) { for (int val : row) System.out.print(val + " "); System.out.println(); } } }
Complexity: O(n * m * p) time, O(n * p) space
Time Complexity
The algorithm uses three nested loops: over rows of first matrix (n), columns of second matrix (p), and the shared dimension (m). This results in O(n * m * p) time.
Space Complexity
The result matrix requires space proportional to the number of rows of the first and columns of the second matrix, O(n * p). No extra large structures are used.
Which Approach is Fastest?
The basic triple loop is the standard and fastest for general cases. Stream-based approaches add overhead and are less efficient but can be more concise.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Triple nested loops | O(n*m*p) | O(n*p) | General use, best performance |
| Method extraction | O(n*m*p) | O(n*p) | Code reuse and clarity |
| Streams (Java 8+) | O(n*m*p) | O(n*p) | Functional style, less performant |