KotlinCS 124 LogoJava
PrevIndexNext
Kotlin
Java
  • Implementing a Map : 04/26/2024

  • Streams : 04/25/2024

  • Generics : 04/24/2024

  • Hashing : 04/23/2024

  • Binary Search : 04/22/2024

  • MP3: Course Ratings : 04/19/2024

  • Quicksort : 04/18/2024

  • Merge Sort : 04/17/2024

  • Sorting Algorithms : 04/16/2024

  • MP Debugging Part 1 : 04/15/2024

  • MP2: Course Activity : 04/12/2024

  • Practice with Recursion : 04/11/2024

  • MP Debugging Part 0 : 04/10/2024

  • MP2: API Client : 04/09/2024

  • MP2: API Server : 04/08/2024

  • Trees and Recursion : 04/05/2024

  • Trees : 04/04/2024

  • Recursion : 04/03/2024

  • MP1: Filtering and Search : 04/02/2024

  • MP1: Loading and Sorting : 04/01/2024

  • Lists Review and Performance : 03/29/2024

  • Linked Lists : 03/28/2024

  • Algorithms and Lists : 03/27/2024

  • Continuing MP0 : 03/26/2024

  • Getting Started with MP0 : 03/25/2024

  • Lambda Expressions : 03/22/2024

  • Anonymous Classes : 03/21/2024

  • Practice with Interfaces : 03/20/2024

  • Implementing Interfaces : 03/19/2024

  • Using Interfaces : 03/18/2024

  • Working with Exceptions : 03/08/2024

  • Throwing Exceptions : 03/07/2024

  • Catching Exceptions : 03/06/2024

  • References and Polymorphism : 03/05/2024

  • References : 03/04/2024

  • Data Modeling 2 : 03/01/2024

  • Equality and Object Copying : 02/29/2024

  • Polymorphism : 02/28/2024

  • Inheritance : 02/27/2024

  • Data Modeling 1 : 02/26/2024

  • Static : 02/23/2024

  • Encapsulation : 02/22/2024

  • Constructors : 02/21/2024

  • Objects, Continued : 02/20/2024

  • Introduction to Objects : 02/19/2024

  • Compilation and Type Inference : 02/16/2024

  • Practice with Collections : 02/15/2024

  • Maps and Sets : 02/14/2024

  • Lists and Type Parameters : 02/13/2024

  • Imports and Libraries : 02/12/2024

  • Multidimensional Arrays : 02/09/2024

  • Practice with Strings : 02/08/2024

  • null : 02/07/2024

  • Algorithms and Strings : 02/06/2024

  • Strings : 02/05/2024

  • Functions and Algorithms : 02/02/2024

  • Practice with Functions : 02/01/2024

  • More About Functions : 01/31/2024

  • Errors and Debugging : 01/30/2024

  • Functions : 01/29/2024

  • Practice with Loops and Algorithms : 01/26/2024

  • Algorithms : 01/25/2024

  • Loops : 01/24/2024

  • Arrays : 01/23/2024

  • Compound Conditionals : 01/22/2024

  • Conditional Expressions and Statements : 01/19/2024

  • Operations on Variables : 01/18/2024

  • Variables and Types : 01/17/2024

  • Welcome to CS 124 : 01/16/2024

Multidimensional Arrays

int[][] pixels = new int[32][32];
for (int i = 0; i < pixels.length; i++) {
for (int j = 0; j < pixels[i].length; j++) {
pixels[i][j] = i + j;
}
}
System.out.println(pixels[8][18]);

This is another extremely exciting lesson. Because now, we’ll learn how to work with even more data. We’ll break free from our linear shackles into full multi-dimensional splendor. Let’s get started!

Debugging Practice
Debugging Practice

But first, let’s get a bit more debugging practice!

Multidimensional Data
Multidimensional Data

So far we’ve worked with single data values, arrays of values, and Strings—which on some level or just character arrays with features. But all of the plural data that we’ve worked with so far has been linear. We’ve learned how to put things in order. But just try linearizing this guy:

It turns out that a lot of the data around us is multidimensional. Photos are just one example.

Multidimensional Arrays
Multidimensional Arrays

Of course Java has a way to work with multidimensional data. And, in many ways, it’s a straightforward extension of what we’ve already seen.

Here’s our first multidimensional array:

int[][] values = new int[8][8];

The syntax is similar to what we saw with single-dimensional arrays. But instead of a single [] in the variable declaration, we have two, indicating a two-dimensional array. How would we do three?

int[][][] values = new int[8][88][8];

Same idea. Also note that on the right side of the initial assignment we can specify sizes for each of the dimensions. The 3-d array shown above has size 8 in the first dimension, 88 in the second dimension, and 8 in the third dimension.

Array indexing in multidimensional arrays works just the same as we’ve seen in the past:

int[][][] values = new int[8][4][2];
System.out.println(values[4][2][1]);
values[2][2][1] = 10;
System.out.println(values[2][2][1]);

And we can still have problems with our bounds if we’re not careful:

int[][][] values = new int[8][4][2];
System.out.println(values[4][2][2]);

Forget Rows and Columns
Forget Rows and Columns

A bi-yearly rant. Forget about rows and columns. Do you want to work with spreadsheets your entire life? This limited mental model will utterly fail you when you need it most!

int[][] samples = new int[2][64];

Arrays of Arrays of Arrays
Arrays of Arrays of Arrays

Let’s explore how multidimensional arrays in Java actually work. Specifically, we’ll talk about why something like this works:

int[][] twod = new int[2][];
int[] oned = new int[8];
twod[1] = oned;
twod[0] = new int[4];
System.out.println(twod.length);
System.out.println(twod[0].length);
System.out.println(twod[1].length);
int[][] twod = new int[4][];

Non-Rectangular Arrays
Non-Rectangular Arrays

Note one important consequence of the fact that Java arrays are arrays of arrays. They do not need to be rectangular! Specifically, an innermost array can have a different size at each index. Some may even be null! Let’s look at how.

int[][] nonrectangular = new int[8][];

If this doesn’t make perfect sense to you, don’t worry. Next we’ll show you patterns that you can use below to work with any array, rectangular or non.

Multidimensional Array Literals
Multidimensional Array Literals

These exist, but they are awful. We’ll never do this to you:

// Holy terrible syntax, Batman!
int[][][] values = new int[][][] {new int[][] {new int[] {1, 2}, new int[] {3}}};
System.out.println(values[0][1][0]);

Practice: Array Sum (Two Dimensional)

Created By: Geoffrey Challen
/ Version: 2020.9.0

Declare and implement a function called arraySum that receives a two-dimensional array of double values as its only parameter and returns the sum of the values in the array as a double. If the array is null you should return 0. None of the inner arrays will be null.

Multidimensional Array Programming Patterns
Multidimensional Array Programming Patterns

Just like single-dimensional arrays, we can develop similar programming patterns for working with multidimensional arrays. Let’s look at an example together.

int[] values = {1, 2, 4};

Practice: 2D Array Max Subarray Sum

Created By: Geoffrey Challen
/ Version: 2021.8.0

Write a method maxSubarraySum that, given a non-rectangular two-dimensional int array, returns the sum of the subarray that sums to the largest value.

So given the following array, with each subarray on a separate line:

1, 2, 4
4, 1, -1
6, 8, -10, -9
-1

You would return 7.

assert that the passed array is not null. However, if the passed array is not null it will contain no empty subarrays.

One hint for this problem is that you may need both an int variable to store the max and a boolean variable to record whether the maximum value has been initialized. Once you have summed each subarray, check whether either your boolean value is false or the sum is larger than the largest you've seen so far. After you check the sum of the first subarray, set your boolean value to true. Another approach is to use the counter that you use to proceed through each subarray to determine whether you have initialized the max value.

Homework: Validate Magic Square

Created By: Geoffrey Challen
/ Version: 2022.8.0

A magic square is a NxN square where the rows, columns, and diagonals all sum to the same value: https://en.wikipedia.org/wiki/Magic_square.

Write a method validateMagicSquare that, given a two-dimensional array of int values, returns whether the array contains a magic square. The passed array may be null, in which case you should return false. However, if it is not null it will contain a non-empty square array, meaning that the size of the array in the first and second dimensions will be the same and greater than zero.

You should check all rows and columns and both diagonals. To determine if all sums are the same, we suggest that you compute an initial sum of any row or column, and then compare all other sums to that value. The choice of how to create the initial sum is arbitrary, but if all sums are the same, then any sum you choose to compare against will work!

We've provided some incomplete starter code to get you going with this problem.

(Note that you do not and should not validate that the magic square is normal, meaning it contains only the numbers from 1 to the size squared. We will pass magic squares that do not have this property.)

boolean validateMagicSquare(int[][] array) {
int size = array.length;
// Finish: Compute the "correct" sum
int correctSum = 0;
// Check either "rows" or "columns"
int currentSum;
// mutate-disable-number-literal
for (int i = 0; i < size; i++) {
currentSum = 0;
for (int j = 0; j < size; j++) {
currentSum += array[i][j];
}
if (currentSum != correctSum) {
return false;
}
}
// Check one diagonal
currentSum = 0;
for (int i = 0; i < size; i++) {
currentSum += array[i][i];
}

Hack4Impact
Hack4Impact

Looking to pursue a new tech project? Seeking opportunities to learn more about UI/UX and design? We are recruiting! We are a student organization connecting non-profits across the globe in need of high-tech solutions with students passionate about building tech for social good. Currently, we are recruiting software developers and product designers—students of all majors and experience levels are welcome!

You can learn more about Hack4Impact here.

More Practice

Need more practice? Head over to the practice page.