A lecture snippet with a mentor as part of the Codegym University course. Sign up for the full course.

"Greetings, Amigo!"

"Hello, Rishi!"

"You already know a thing or two about arrays, and you even managed to solve some tasks, I hope. But you don't know everything. For example, here's another interesting fact about arrays. Arrays are not only one-dimensional (linear). They can also be two-dimensional."

"Um... What does that mean?"

"This means that the cells of the array can represent not only a column (or row), but also a rectangular table.

int[][]name = new int[width][height];

"Where name is the name of the array variable, width is the table width (in cells), and height is the table height. Take a look at an example:

int[][] data = new int[2][5];
data[1][1] = 5;
We create a two-dimensional array: 2 columns and 5 rows.
We write 5 in cell (1,1).

"This is how it will look in memory:

Two-dimensional arrays

"By the way, for two-dimensional arrays, you can also use fast initialization:

// Lengths of months of the year in each quarter
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };

"Hmm... now that's interesting. If we imagine that in the first inner brackets represent one element, the next is a second... So a two-dimensional array is like an array of arrays?"

"What a smart student you are! Exactly. The first element is the one-dimensional array {31, 28, 31}, the second is {30, 31, 30}, and so on. But we'll come back to that a little later in this lesson. Until then, try to think of a two-dimensional array as a table with rows and columns, forming cells at each intersection.

"I've got a mental picture of that. By the way, what are they used for, these two-dimensional arrays?"

"Programmer need two-dimensional arrays quite often. If you look closely, almost any board game is implemented using an off-the-shelf two-dimensional array: chess, checkers, tic-tac-toe, sea battle, etc.:"

sea battle

"I get it! The playing field of chess or sea battle fits perfectly onto two-dimensional arrays!"

"Yes, but you need to use numbers as the cell coordinates. Not 'pawn e2-e4', but 'pawn (5,2) -> (5,4)'. It will be even easier for you as a programmer."

Arranging elements in arrays: (x, y) or (y, x)

"Creating two-dimensional arrays raises an interesting dilemma. When we create an array using new int [2][5];, do we have a table of 'two rows and 5 columns' or is it 'two columns and 5 rows'?"

"In other words, it is not entirely clear whether we are first specifying the width and then the 'height... or vice versa, first the height and then width?"

"Yes, this is the dilemma. And there is no definite answer."

"What to do?"

"First, it is important to understand how our two-dimensional array is actually stored in memory. Naturally, computer memory doesn't actually have any tables in it: each location in memory has a sequential numeric address: 0, 1, 2, ... For us, this is a 2 × 5 table, but in memory it is just 10 cells, nothing more. No division into rows and columns."

"I understood that. How then do we determine which dimension comes first — the width or the height?"

"Let's consider the first option. Width first, then height. "The argument in favor of this approach is this: everyone learns math in school, and they learn that coordinate pairs are written as 'x' (that is, the horizontal axis) and then 'y' (the vertical dimension). And this is not just a school standard — it's a generally accepted standard in mathematics. As they say, you can't argue with math."

"Is that so? Well, if we can't fight it, then first the width and then the height?"

"There is an interesting argument in favor of 'height first, then width'. This argument comes from fast initialization of two-dimensional arrays. After all, if we want to initialize our array, then we write code like this:"

// Matrix of important data
int[][] matrix = { {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5} };

"So what does that do for us?"

"Did you notice anything? What if we have this?

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {1, 2, 3, 4, 5}

"If we write our data in the code line by line, then we get a table with 2 rows and 5 columns."

"Now I see. 2 is the height, and 5 is the width... So then which option should we use?"

"It's up to you to decide which is more convenient. The most important thing is that all programmers working on the same project stick to the same approach."

"If you work on a project whose code has lots of initialized two-dimensional arrays, then most likely everything there will be based on fast data initialization, i.e. you'll have the standard 'height x width'.

"If you find yourself in a project involving a lot of mathematics and working with coordinates (for example, game engines), then the code will most likely adopt the 'width x height' approach.

How two-dimensional arrays are arranged

"Now, do you remember the special feature of two-dimensional arrays that you noticed at the beginning of the lesson?"

"Yes! It was that two-dimensional arrays are actually arrays of arrays!"

"Quite right. "In other words, if in the case of an ordinary array an array variable stores a reference to a container that stores array elements, then in the case of two-dimensional arrays the situation explodes a little: a two-dimensional-array variable stores a reference to a container that stores references to one-dimensional arrays. It's better to see it in action once rather than try to explain it a hundred times:"

How two-dimensional arrays are arranged

"On the left, we have a two-dimensional-array variable, which stores a reference to a two-dimensional-array object. In the middle there is a two-dimensional array object whose cells store one-dimensional arrays, which are the rows of a two-dimensional array. And on the right, you can see four one-dimensional arrays — the rows of our two-dimensional array. This is how two-dimensional arrays actually work."

"Fantastic! But what does it give us?"

"Since a 'container of containers' stores references to 'arrays of rows', we can very quickly and easily swap rows. To get a 'container of containers', you just need to specify one index instead of two. Example:

int[][] data = new int[2][5];
int[] row1 = data[0];
int[] row2 = data[1];

"Look at the code below. We can use it to swap rows:"

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {5, 4, 3, 2, 1}

int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
Two-dimensional array

matrix[0] stores a reference to the first row.
We swap the references.

As a result, the matrix array looks like this:
  {5, 4, 3, 2, 1},
  {1, 2, 3, 4, 5}

"Got it. It works like swapping any two ordinary items."

"So it does. Well, if you refer to a cell of a two-dimensional array, but you only specify one index after the name of the array, then you are referring to a container of containers whose cells store references to ordinary one-dimensional arrays."

"Everything seems logical and clear. Thanks for the lecture, Rishi!"

"You are welcome. Put it into practice wisely."

New Java Syntax,  level 6lesson 5
Multiplication table
Initialize the MULTIPLICATION_TABLE array as a new int[10][10], fill it with a multiplication table, and then display it on the console in the following form: 1 2 3 4 … 2 4 6 8 … 3 6 9 12 … 4 8 12 16 … … The numbers in each line are separated by a space.