Многомерные массивы

В Java многомерные массивы представляют собой массивы массивов. Они, как можно догадаться, выглядят и действуют подобно обычным многомерным массивам. Однако, как вы увидите, им присущи и несколько незначительных отличий. При объявлении переменной многомерного массива для указания каждого дополнительного индекса используют отдельный набор квадратных скобок. Например, следующий код объявляет переменную двумерного массива twoD.

int twoD[] [] = new int[4] [5] ;

Этот оператор распределяет память для массива размерностью 4x5 и присваивает его переменной twoD. Внутренне эта матрица реализована как массив массивов значений типа int. С точки зрения логической организации этот массив будет выглядеть подобно изображенному на рис. 3.1.

Рис. 3.1. Логическое представление двумерного массива 4x5

Следующая программа нумерует элементы в массиве слева направо, сверху вниз, а затем отображает эти значения.

// Демонстрация двумерного массива.
class TwoDArray {
public static void main(String args[]) {
int twoD[] []= new int[4] [5] ;
int i, j, к = 0;
for(i=0; i<4; i++)
for(j=0; j<5; j++) ( twoD[i] [j] = k; k++;
}
for(i=0; i<4; i++) ( for(j=0; j<5; j++)
System.out.print(twoD[i][j] + " "); System.out.println() ;
}
}
}

Эта программа генерирует следующий вывод:

0 12 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19

При распределении памяти под многомерный массив необходимо указать память только для первого (левого) измерения. Для каждого из остальных измерений память можно распределять отдельно. Например, следующий код резервирует память для первого измерения массива twoD при его объявлении. Распределение памяти для второго измерения массива осуществляется вручную.

int twoD[][] = new int[4 ] [ ] ;
twoD[0] = new int[5];
twoD[l] = new int[5];
twoD[2] = new int[5];
twoD[3] = new int[5];

Хотя в данной ситуации отдельное распределение памяти для второго измерения массива и не дает никаких преимуществ, в других ситуациях это может быть полезно. Например, при распределении памяти для измерений массива вручную не нужно распределять одинаковое количество элементов для каждого измерения. Как было отмечено ранее, поскольку в действительность многомерные массивы представляют собой массивы массивов, программист полностью управляет длиной каждого массива. Например, следующая программа создает двумерный массив с различными размерами второго измерения.

// Резервирование памяти вручную для массива с различными
// размерами второго измерения.
class TwoDAgain {
public static void main(String args[]) {
int twoD[] [] = new int [4] [] ;
twoD[0] = new int[l];
twoD[l] = new int[2];
twoD[2] = new int[3] twoD[3] = new int[4];
int i, j, k = 0;
for(i=0; i<4; i++)
for (j=0; j twoD[i][j] = k; k++;
}
for(i=0; i<4; i++) { for(j=0; j System.out.print(twoD[i][j] + " "); System.out.println() ;
}
}
}

Эта программа генерирует следующий вывод:

0
1 2
3 4 5
6 7 8 9

Созданный ею массив выглядит, как показано на рис. 3.2.

Рис. 3.2. Двумерный массив с различными размерами второго измерения

Использование неоднородных (или нерегулярных) массивов может быть не применимо во многих приложениях, поскольку их поведение отличается от обычного поведения многомерных массивов. Однако в некоторых ситуациях нерегулярные массивы могут оказаться весьма эффективными. Например, нерегулярный массив может быть идеальным решением, если требуется очень большой двумерный разреженный массив (т.е. массив, в котором будут использоваться не все элементы).

Многомерные массивы можно инициализировать. Для этого достаточно заключить инициализатор каждого измерения в отдельный набор фигурных скобок. Следующая программа создает матрицу, в которой каждый элемент содержит произведение индексов строки и столбца. Обратите также внимание, что внутри инициализаторов массивов можно применять как значения констант, так и выражения.

// Инициализация двумерного массива.
class Matrix {
public static void main(String args[]) { double m[] [] = {
( 0*0, 1*0, 2*0, 3*0 }, ( 0*1, 1*1, 2*1, 3*1 }, ( 0*2, 1*2, 2*2, 3*2 }, { 0*3, 1*3, 2*3, 3*3 }
);
int i, j;
for(i=0; i<4; i++) { for(j=0; j<4;
System.out.print (m[i] [j] + " "); System.out.println();
}
}
}

При выполнении эта программа генерирует следующий вывод:

0.0 0.0 0.0 0.0
0.0 1.0 2.0 3.0
0.0 2.0 4.0 6.0
0.0 3.0 6.0 9.0

Как видите, каждая строка массива инициализируется в соответствии со значениями, указанными в списках инициализации.

Рассмотрим еще один пример использования многомерного массива. Следующая программа создает трехмерный массив размерности 3x4x5. Затем она загружает каждый элемент произведением его индексов. И, наконец, она отображает эти произведения.

// Демонстрация трехмерного массива.
class ThreeDMatrix {
public static void main(String.args[J) {
int threeD[] [] [] = new int[3] ,[4] [5] ;
int i, j, k;
for(i=0; i<3; i++)
for(j=0; j<4; j++) for(k=0; k<5; k++) threeD[i] [j] [k] = i * j * k;
for(i=0; i<3; i++) { for(j=0; j<4; j++) { for(k=0; k<5; k++)
System, out. print (threeD[i]: [j] [k] + " ");
System.out.println ();
}
System.out.println();
}
}
}

Эта программа генерирует следующий вывод:

0 0 0 0 0
0 1 2 3 4
0 2 4 6 8
0 3 б 9 12

0 0 0 0 0
0 2 4 6 8
0 4 8 12 16
0 6 12 18 24