Introduction

Finding the sum of each column in a 2D array is another common matrix operation in Java. While it looks similar to calculating row sums, the implementation is slightly different because Java stores a 2D array as an array of rows.

To calculate a column sum, you must keep the column fixed and iterate through every row, collecting the values in that column. This requires swapping the order of the loops compared to the row-sum problem.

In this tutorial, you'll learn multiple approaches to calculate the sum of each column in a 2D array, including nested loops and Java Streams. You'll also learn how to handle jagged arrays, common mistakes to avoid, and best practices.

Advertisement

Problem Statement

Given the following 2D array:

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

The expected column sums are:

 
Column 0 = 12
Column 1 = 15
Column 2 = 18
 

Or as an array:

 
[12, 15, 18]
 

Why Column Sums Are Different from Row Sums

In Java, a 2D array is actually an array of row arrays.

When calculating row sums, you simply move across one row at a time.

When calculating column sums, you must jump from one row to another while keeping the same column index.

For example, to calculate the first column:

 
1
4
7
 

You access:

 
matrix[0][0]
matrix[1][0]
matrix[2][0]
 

This is why the loop order is different from the row-sum solution.


The simplest and most efficient approach is to swap the loop order.

  • The outer loop iterates through columns.
  • The inner loop iterates through rows.

Java Program

 
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {

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

        int numCols = matrix[0].length;
        int[] columnSums = new int[numCols];

        for (int col = 0; col < numCols; col++) {

            int currentColumnSum = 0;

            for (int row = 0; row < matrix.length; row++) {

                currentColumnSum += matrix[row][col];
            }

            columnSums[col] = currentColumnSum;
        }

        System.out.println(Arrays.toString(columnSums));
    }
}
 

Output

 
[12, 15, 18]
 

Time Complexity

O(rows × columns)

Space Complexity

O(columns)


Method 2: Using Java Streams

Java Streams provide a concise functional approach.

Java Program

 
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {

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

        int numCols = matrix[0].length;
        int[] columnSums = new int[numCols];

        for (int col = 0; col < numCols; col++) {

            final int currentCol = col;

            columnSums[col] = Arrays.stream(matrix)
                                    .mapToInt(row -> row[currentCol])
                                    .sum();
        }

        System.out.println(Arrays.toString(columnSums));
    }
}
 

Output

 
[12, 15, 18]
 

How It Works

  • The outer loop selects one column.
  • Arrays.stream(matrix) creates a stream of rows.
  • mapToInt() extracts the value from the selected column in every row.
  • sum() calculates the total for that column.

Handling Jagged Arrays

Column sums become slightly more complicated for jagged arrays because rows can have different lengths.

A common solution is to determine the widest row and ignore missing values in shorter rows.

Java Program

 
import java.util.Arrays;

public class Main {

    public static int[] sumColumnsJagged(int[][] matrix) {

        int maxColumns = 0;

        for (int[] row : matrix) {
            maxColumns = Math.max(maxColumns, row.length);
        }

        int[] columnSums = new int[maxColumns];

        for (int[] row : matrix) {

            for (int col = 0; col < row.length; col++) {

                columnSums[col] += row[col];
            }
        }

        return columnSums;
    }

    public static void main(String[] args) {

        int[][] jagged = {
            {1,2},
            {3,4,5},
            {6}
        };

        System.out.println(Arrays.toString(sumColumnsJagged(jagged)));
    }
}
 

Output

 
[10, 6, 5]
 

Here:

  • Column 0 → 1 + 3 + 6 = 10
  • Column 1 → 2 + 4 = 6
  • Column 2 → 5

Step-by-Step Explanation

Consider the following code:

 
for (int col = 0; col < numCols; col++) {

    int currentColumnSum = 0;

    for (int row = 0; row < matrix.length; row++) {

        currentColumnSum += matrix[row][col];
    }

    columnSums[col] = currentColumnSum;
}
 

Here's what happens:

  1. Determine the number of columns.
  2. Select the first column.
  3. Visit every row while keeping the column fixed.
  4. Add each value to currentColumnSum.
  5. Store the result in columnSums[col].
  6. Repeat for every remaining column.

Unlike row sums, the outer loop iterates over columns.


Internal Working

For the following matrix:

 
{
    {1,2,3},
    {4,5,6},
    {7,8,9}
}
 

The calculation proceeds as follows:

 
Column 0

1 + 4 + 7 = 12
columnSums[0] = 12

Column 1

2 + 5 + 8 = 15
columnSums[1] = 15

Column 2

3 + 6 + 9 = 18
columnSums[2] = 18

Final Result

[12, 15, 18]
 

Notice that every column calculation accesses values from different rows.


Real-Life Analogy

Imagine a spreadsheet containing monthly sales data.

Each row represents a different salesperson, while each column represents a month.

To find the total sales for January, you read down the January column, adding one value from every salesperson's row.

You repeat the same process for February, March, and every remaining month.


Best Practices

  • Use the swapped loop order (outer loop for columns, inner loop for rows).
  • Validate that the matrix is rectangular before using matrix[0].length.
  • Use matrix[0].length only when every row has the same number of columns.
  • Handle jagged arrays separately if rows can have different lengths.
  • If both row sums and column sums are required, compute them together in a single traversal to improve efficiency.

Common Mistakes

Using the Same Loop Order as Row Sums

Incorrect:

 
for (int row = 0; row < matrix.length; row++)
 

This calculates row sums instead of column sums.

Correct:

 
for (int col = 0; col < numCols; col++)
 

Assuming Every Matrix Is Rectangular

Incorrect:

 
matrix[row][col]
 

without checking row length.

This may throw an ArrayIndexOutOfBoundsException for jagged arrays.


Creating the Result Array with the Wrong Size

Incorrect:

 
int[] columnSums = new int[matrix.length];
 

Correct:

 
int[] columnSums = new int[matrix[0].length];
 

Ignoring Empty Matrices

Before accessing matrix[0], verify that the matrix contains at least one row.


Expert Tips

  • Swapping the loop order is a common technique used in many matrix algorithms.
  • Column-wise access is generally less cache-friendly than row-wise access because Java stores arrays row by row.
  • If you frequently perform column operations, consider transposing the matrix first and then using row-based algorithms.
  • If both row sums and column sums are required, compute them together during one traversal instead of scanning the matrix twice.

Comparison of Row Sums and Column Sums

Feature Row Sum Column Sum
Outer loop Rows Columns
Inner loop Columns Rows
Result size Number of rows Number of columns
Handles jagged arrays ✅ Naturally ⚠ Requires special handling
Cache efficiency High Lower

Frequently Asked Questions

Why is calculating column sums different from row sums?

Because Java stores data row by row. A column sum requires reading one element from each row instead of traversing a single row.


Does this approach require a rectangular matrix?

Yes. The basic solution assumes that every row contains the same number of columns. Jagged arrays require additional handling.


What is the main difference in the code?

The loop order is swapped.

  • Row sums → outer loop over rows.
  • Column sums → outer loop over columns.

Can I use Java Streams?

Yes. Streams work well for column sums, although you still need an outer loop to iterate through each column.


Why is column-wise traversal slower?

Because consecutive accesses jump between different row arrays instead of reading contiguous elements within a single row.


How do I handle jagged arrays?

Determine the widest row, create the result array accordingly, and only add values that exist in each row.


Can I calculate row sums and column sums together?

Yes. During a single traversal, update both the current row sum and the corresponding column sum array.


Does matrix transposition help?

Yes. After transposing a matrix, the original columns become rows, allowing you to reuse row-based algorithms for many column operations.