2D Arrays
The goal of this lab period is to practice using 2D arrays in Java. Unlike last week and unlike in most of the other labs you will do this semester, you are not building a Grid class that you will use to store data in your project. This lab is designed to be practice with 2-D arrays that will prepare you for the work in the project, but won't be used directly. You do need to do it to get credit for the lab checkpoint!
What you will build today
One file: Grid.java (one class with a main method)
- Create one rectangular 2D array and print it
- Create one non-rectangular (jagged) 2D array and print it
- Show the difference between == (references) and comparing values
- Write gridEquals(int[][], int[][])
- Use two command line arguments to change program behavior
- Optional: transpose a rectangular grid and print before/after
Checkpoint Requirements (quick checklist)
- Rectangular grid created + printed
- Jagged grid created + printed
- gridEquals works on equal and non-equal grids
- Two command line arguments affect what your program does
- Program prints a usage statement and exits if fewer than 2 args are provided
- README.txt explains how to run your program
+ Common Mistakes (click to expand)
- Printing a 2D array directly: System.out.println(grid) prints a reference, not the contents.
- Using grid.length for columns — you usually want grid[r].length.
- Accessing a jagged row before allocating it (null row): e.g., reading grid2[0][0] before grid2[0] = new int[...];.
Lab Steps
-
Step 1 — Setup
Create a working directory for today's lab/project, then download this Grid.java file and this example README. This is where you will write your code for this lab.
-
Step 2 — Creating 2D Arrays
Task A — Declare and allocate a rectangular grid
In your main method, create a 2D array of type int. In the example below, we'll call it grid (this defines but doesn't instantiate it):
int[][] grid;Allocate the 2D array in a single new statement, giving it 3 rows and 5 columns:
grid = new int[3][5];The first set of square brackets corresponds to the rows, and the second set corresponds to the columns.
Task B — Allocate a jagged (non-rectangular) grid
Now try an alternative method: allocate the number of rows first, then allocate each row separately. This lets you create rows with different lengths.
int[][] grid2 = new int[3][]; for (int i = 0; i < 3; i++) { grid2[i] = new int[i + 1]; }Be a little careful with this method: if you try to access
grid2[0][0]before the loop runs, what happens?Rectangular vs jagged (visual)Rectangular: [ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ] Jagged: [ ] [ ][ ] [ ][ ][ ]
Task C — Fill both grids with random ints
Fill
gridandgrid2by visiting every location with a nested loop and assigning a random integer.- Use a nested loop
- Visit every (row, col)
- Assign a random int to each location
+ (More Detail)
When working with 2-D arrays we often use nested for loops:
for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[i].length; j++) { /* access grid[i][j] */ } }This example iterates over all of the elements in the rectangular
grid. You will need to generalize this forgrid2or other 2-D arrays by usinggrid2[i].lengthfor each row.Remember: you have to use different names for nested loop variables. For almost all 2-D arrays, loop over rows in the outer loop and columns in the inner loop. Many 2-D arrays are stored in row-major order, so this access pattern tends to be faster.
While you can hard-code the number of rows and columns into the loops (e.g. 3 and 5), using
grid.lengthandgrid[i].lengthis less error-prone.Tip: you can start by assigning a constant value (like 4) to verify your loops work, then replace the constant with a randomly generated integer.
-
Step 3 — Print the Contents of the 2-D Array
If you try to print
griddirectly, what happens? You’ll likely see something likeint@somegarbage(a reference). Java arrays don’t implement a “pretty” toString, so you need nested loops to print the contents.Print the contents of each 2D array as a 2D grid using nested loops. Make it look nice (the exact formatting is up to you as long as it is clear).
+ (More Detail)
System.out.printdoes not add a newline.System.out.printlndoes add a newline. When printing a 2-D array, keep all elements in a row on the same line, then print a newline between rows.Example output:
1 2 7 8 9 3 4 6 1 2 2 4 7 6 0
If you want control over formatting (especially floating point numbers), look at
System.out.printfand printf formatting codes. -
Step 4 — Concept Shift: References vs Values
Add the following code to your main method:
int[][] arr1 = new int[2][2]; int[][] arr2 = new int[2][2]; int[][] arr3; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { arr1[i][j] = i + j; arr2[i][j] = i + j; } } arr3 = arr1;This code generates 3 new 2-D arrays,
arr1,arr2, andarr3, all of which contain the same values. This allows you to explore what it means for 2 2-D arrays to be equal in Java.Add code below that block that checks (using
==) whether:arr1is equal toarr2arr1is equal toarr3
Important:==tests whether two variables refer to the same object (same reference), not whether two arrays contain the same values.Your next task is to write a method named
gridEqualsthat checks whether two 2D arrays contain identical values in the same locations. Your method should have this declaration:public static boolean gridEquals(int[][] arr1, int[][] arr2)Test that:
gridEquals(arr1, arr3)returnstruegridEquals(arr1, grid)returnsfalse(wheregridis your random rectangular grid)
-
Step 5 — Adding Command-line Arguments
The args parameter of main() contains strings from the command line. You can see this by printing the elements of the args array, then running your program a few different times. For example (after compiling
Grid.java), try:java Grid a b c djava Grid hello world command line argumentYour goal: use two command line arguments to change your program’s behavior. What they do is up to you (surprise us!). Some ideas:
- Specify the size (rows and/or columns) of the rectangular grid
- Specify the random range for grid values
- Create a boolean flag for positive/negative values
- Pass in actual values instead of random generation
By this point, your code should already be able to:
- Create 1 rectangular 2-D array and print its contents
- Create 1 non-rectangular 2-D array and print its contents
- Show that
gridEqualsworks on equal and non-equal grids - Use 2 command line parameters to affect the program
Keeping the steps in this exact order is not required — if you’ve been following along, your program should already do all of these things.
-
Step 6 — Usage Statements
Many programs require command line arguments to work properly. To be kind to users, you should check for enough arguments and print a usage statement if they are missing.
+ Java example usage output (optional reading)
Usage: java [options] <mainclass> [args...] (to execute a class) or java [options] -jar <jarfile> [args...] (to execute a jar file) or java [options] -m <module>/<mainclass> [args...] java [options] --module <module>/<mainclass> [args...] (to execute the main class in a module) or java [options] <sourcefile> [args] (to execute a single source-file program) ...At the very top of your main method, check whether the user provided at least two command line arguments. If not, print a usage statement and return. If yes, run your program normally.
Your usage statement does not need to match the Java example above. It should clearly say:
- How to run your program
- What the arguments mean
- Why the user’s input was not acceptable (e.g., missing args)
Run
Grid.javawith no arguments, one argument, and with two or more arguments. It should print your usage statement in the first two cases, and run normally in the last case. -
Step 7 — Creating a README File
Usage statements are one way to communicate how to run your program. README files are another. You should include both so that a user can run your program correctly.
For this lab, your README file should follow these rules:
- Download the
README.txttemplate from the Google Classroom and add it to your main project folder - Follow the instructions in the file.
Lab checkpoint: Call a lab TA or instructor over and show us your README file. Have us try to run your program (don't tell us anything not in the README). If we're able to run your program correctly, you will get credit for the checkpoint!
- Download the
-
Step 8 (Optional) — Transposing a Matrix
Create a function with the following declaration:
public static int[][] transpose(int[][] arr). This function should transpose a rectangular grid.Example:
Original: 1 2 3 4 5 6 Transposed: 1 3 5 2 4 6
You may assume the grid is rectangular (all rows have the same length).
It is highly recommended that you draw a picture showing where each element moves:
original[row][col]goes totransposed[newRow][newCol]. Determine how to computenewRowandnewColfromrowandcol, and how the transposed grid’s size relates to the original.At this point, your output should clearly show:
- Original grid
- Transposed grid
When you are done with the lab, go ahead and get started on the current project.