— Не хватает некоторых деталей. Но не в этом суть!
Из к/ф «Приключения Шерлока Холмса
и доктора Ватсона»
В Java массивы могут иметь размерность выше единичной. Но на практике мас- сивы размерности выше второй используют редко. Вначале рассмотрим спосо- бы объявления, инициализации и использования двухмерных массивов.
Двухмерный массив в Java с технической точки зрения является одномерным массивом, элементами которого являются также одномерные массивы. Это на первый взгляд несущественное обстоятельство приводит к исключительной гибкости в использовании таких структур, как двухмерные массивы.
Объявляются двухмерные массивы практически так же, как и одномерные, с той лишь разницей, что при этом используются две пары квадратных скобок (как при объявлении переменной массива, так и при выделении для массива области памяти). При этом размер массива указывается по каждому из индексов. Син- таксис объявления двухмерного массива может быть следующим:
тип[][] имя=new тип[размер_1][размер_2];
Как и в случае одномерного массива, данная команда представляет собой объ- единение двух отдельных команд:
тип[][] имя;
имя=new тип[размер_1][размер_2];
Первой из них объявляется переменная двухмерного массива имя. Второй ко- мандой создается двухмерный массив с размерами размер_1 и размер_2, а ссылка
на этот массив присваивается в качестве значения переменной массива имя. На- пример, командой double[][] data=new double[3][4] создается массив с именем data. Элементами массива являются значения типа double. Размер массива по первому индексу равен 3, а по второму — 4. К тому же результату приведет вы- полнение команд
double[][] data; data=new double[3][4];
Обращение к элементам двухмерного массива выполняется в следующем фор- мате: указывается имя массива, в квадратных скобках первый индекс элемента и в квадратных же скобках второй элемент массива. Индексация по всем раз- мерностям начинается с нуля. Например, ссылка data[0][3] является обращени- ем к элементу массива data с индексами 0 и 3.
Для инициализации двухмерного массива используют вложенные инструкции цикла или список значений, заключенный в фигурные скобки. Элементами спи- ска являются заключенные в фигурные скобки списки значений элементов по каждому из индексов. Пример инициализации двухмерного массива с помощью списка значений:
double data[][]={{0.1,0.2,0.3},{0.4,0.5,0.6}}; int nums[][]={{1,2,3},{4,5}};
Первой командой создается и инициализируется двухмерный массив data раз- мерами 2 на 3 (по первому индексу размер массива 2, по второму индексу — 3). Другими словами, массив data — это массив из двух элементов, которые, в свою очередь, являются массивами из трех элементов. Так, элемент data[0][0] полу- чает значение 0.1, элемент data[0][2] — значение 0.3, элемент data[1][0] — зна- чение 0.4, а элемент data[1][2] — значение 0.6.
Интереснее вторая команда. Этой командой создается целочисленный массив nums, который состоит из двух элементов-массивов. Однако первый массив име- ет размерность 3, а второй — 2! Здесь мы находим подтверждение того, что в Java двухмерные массивы не обязаны быть прямоугольными, то есть иметь такую же размерность по второму индексу. В данном случае элемент nums[0][0] имеет значение 1, элемент nums[0][1] — значение 2, элемент nums[0][2] — значение 3, элемент nums[1][0] — значение 4, а элемент nums[1][1] — значение 5. Элемента nums[1][2] не существует вообще!
В листинге 3.2 приведен пример программы, в которой создается двухмерный массив и инициализируется с помощью вложенных инструкций цикла.
Листинг 3.2.Объявление и инициализация двухмерного массива
class MyDArray{
public static void main(String[] args){
// Индексные переменные и размерность массива: int i,j,n=3;
// Создание двухмерного массива: int[][] nums=new int[n-1][n];
// Вложенные инструкции цикла:
for(i=0;i<n-1;i++){ for(j=0;j<n;j++){
// Заполнение элементов массива: nums[i][j]=10*(i+1)+j+1;
// Вывод значений в одну строку: System.out.print(nums[i][j]+" ");}
// Переход на новую строку System.out.println();}
}
}
Командой int[][] nums=new int[n-1][n] создается целочисленный массив nums с размерами n-1 по первому индексу и n по второму. Переменная n предва- рительно инициализирована со значением 3. Заполняется массив с помощью вложенных инструкций цикла (команда nums[i][j]=10*(i+1)+j+1). Значения эле- ментов массива выводятся на экран. В результате выполнения программы по- лучаем:
11 12 13
21 22 23
В листинге 3.3 приведен код программы, в которой создается двухмерный «не- прямоугольный» массив.
Листинг 3.3.Создание непрямоугольного массива
class ArrayDemo{
public static void main(String[] args){
// Индексные переменные и размер массива: int i,j,n;
// Создание массива (второй размер не указан): int[][] nums=new int[5][];
// Определение первого размера массива: n=nums.length;
// Цикл для создания треугольного массива: for(i=0;i<n;i++){
nums[i]=new int[i+1];}
// Вложенные циклы для заполнения элементов массива: for(i=0;i<n;i++){
for(j=0;j<nums[i].length;j++){
// Присваивание значения элементу массива: nums[i][j]=10*(i+1)+j+1;
// Вывод значения на экран: System.out.print(nums[i][j]+" ");}
продолжение
Листинг 3.3(продолжение)
// Переход на новую строку: System.out.println();}
}
}
Обращаем внимание читателя на команду int[][] nums=new int[5][], которой создается двухмерный целочисленный массив nums. Этот массив состоит из пяти элементов, каждый из которых также является массивом. Однако размер этих массивов не указан — вторая пара квадратных скобок в конце програм- мы пуста! Определяются размеры каждого из элементов-массивов в рамках инструкции цикла, но предварительно переменной n командой n=nums.length присваивается значение размера массива по первому индексу. Ранее уже упо- миналось, что двухмерный массив является массивом массивов. Поэтому ссылка nums.length возвращает размер массива nums, то есть число 5 в данном случае.
В первой инструкции цикла индексная переменная i получает значения от 0 до n-1. Командой nums[i]=new int[i+1] определяются размеры каждого из мас- сивов — элементов массива nums. Учитывая, что nums является двухмерным мас- сивом, инструкция вида nums[i] является ссылкой на i-й одномерный элемент- массив массива nums. Командой new int[i+1] выделяется место в памяти для массива, размер этого массива устанавливается равным i+1, а ссылка на массив записывается в переменную nums[i]. В результате мы получаем двухмерный мас- сив «треугольного» вида: в первой «строке» массива один элемент, во второй — два элемента и т. д., до пятой «строки» массива.
С помощью вложенных инструкций цикла выполняется заполнение созданно- го массива. Внешняя индексная переменная i получает значения от 0 до n-1 и определяет первый индекс двухмерного массива nums. Верхняя граница диа- пазона изменения второй индексной переменной j, определяющей второй ин- декс элемента массива nums, зависит от текущего значения переменной i. Для определения размера массива nums[i] используется инструкция nums[i].length. Индекс j изменяется от 0 до nums[i].length-1. Значение элементам массива при- сваивается командой nums[i][j]=10*(i+1)+j+1. Результат выполнения программы имеет вид:
21 22
31 32 33
41 42 43 44
51 52 53 54 55
Практически также создаются многомерные (размерности выше второй) мас- сивы. В листинге 3.4 приведен пример создания трехмерного массива размером три по каждому из индексов, определяющего тензор Леви–Чевита. Компоненты этого тензора имеют три индекса и отличны от нуля, только если все индексы различны. Элемент с индексами 0, 1 и 2 равен единице. Любой элемент, который получается циклической перестановкой этих индексов, также равен 1. Прочие
Символьные массивы87
элементы равны –1. Таким образом, всего три единичных элемента и три эле- мента со значением –1, остальные равны нулю.
// Обнуление элементов массива: for(i=0;i<3;i++) for(j=0;j<3;j++) for(k=0;k<3;k++) epsilon[i][j][k]=0;
// Единичные элементы массива: epsilon[0][1][2]=epsilon[1][2][0]=epsilon[2][0][1]=1;
// Элементы со значением -1: epsilon[1][0][2]=epsilon[0][2][1]=epsilon[2][1][0]=-1;
}
}
Объявляется трехмерный массив epsilon командой byte[][][] epsilon=new byte[3][3][3]. Для надежности всем элементам массива присваиваются нулевые значения, для чего используется три вложенных инструкции цикла. Далее ко- мандой epsilon[0][1][2]=epsilon[1][2][0]=epsilon[2][0][1]=1 задаются единичные значения для трех элементов массива и еще для трех элементов значение -1 (ко- мандой epsilon[1][0][2]=epsilon[0][2][1]=epsilon[2][1][0]=-1).