Представьте себе ячейки в камере хранения. Каждая из них имеет свой номер, и в каждой из них хранится какой-то объект “Багаж”. Или винная карта, в которой все виды вина пронумерованы и когда вы делаете заказ, вам достаточно назвать номер напитка. Или список студентов группы, в котором в первой ячейке будет записан студент “Андреев”, а в последней - “Яковлев”. Или список пассажиров самолёта, за каждым из которых закреплено место с определённым номером. В Java чтобы работать с подобными структурами, то есть множеством однородных данных, часто используют массивы.
Статьи на поиск и сортировку: Сортировка и поиск в курсе CS50: |
Главные характеристики массива: тип помещённых в него данных, имя и длина.
Последнее решается при инициализации (выделении памяти под массив), первые два параметра определяются при объявлении массива.
Размер массива (количество ячеек) нужно определять в int
Изменить длину массива после его создания нельзя.
Доступ к элементу массива можно получить по его индексу.
В массивах, как и везде в Java, элементы нумеруются с нуля.
После процедуры создания массива он наполнен значениями по умолчанию.
Массив в языке Java значительно отличается от массива в языке C++. Однако он практически совпадает с указателем на динамический массив.
Кое-что о массивах - хорошая подробная статья о массивах
Класс Arrays и его использование - в статье описаны некоторые методы класса Array
Массивы первая лекция JavaRush, посвящённая массивам.
Возвращайте массив нулевой длины, а не null - автор “Эффекктивного программирования” Джошуа Блох рассказывает о том, как лучше возвращать пустые массивы
Массив - это структура данных, в которой хранятся величины одинакового типа. Доступ к отдельному элементу массива осуществляется с помощью целого индекса. Например, если а - массив целых чисел, то значение выражения а [ i ] равно i-му целому числу в массиве.
Массив объявляется следующим образом: сначала указывается тип массива, т.е тип элементов, содержащихся в массиве, за которым ставится пара пустых квадратных скобок, а затем - имя переменной. Например, вот как объявляется массив, состоящий из целых чисел:
int a;
Однако этот оператор лишь объявляет переменную а, не инициализируя ее настоящим массивом. Чтобы создать массив, нужно применить оператор new.
Этот оператор создает массив, состоящий из 100 целых чисел. Элементы этого массива нумеруются от 0 до 99 (а не от 1 до 100). После создания массив можно заполнять, например, с помощью цикла.
int а = new int;
for (int i = 0; i < 100; i++)
a[i] = i; // Заполняет массив числами от 0 до 99.
Если вы попытаетесь обратиться к элементу а (или любому другому элементу, индекс которого выходит за пределы диапазона от 0 до 99), создав массив, состоящий из 100 элементов, программа прекратит работу, поскольку возникнет исключительная ситуация, связанная с выходом индекса массива за пределы допустимого диапазона.
Чтобы подсчитать количество элементов в массиве, используйте метод имяМасси-
ва.length.
Например,
for (int i = 0; i < a. length; i++ System.out.println (a[i]);
После создания массива изменить его размер невозможно (хотя можно, конечно, изменять отдельные его элементы). Если в ходе выполнения программы необходимо часто изменять размер массива, лучше использовать другую структуру данных, называемую списком массивов (array list).
Массив можно объявить двумя способами:
int a;
или
int a;
Большинство программистов на языке Java предпочитают первый стиль, поскольку в нем четче отделяется тип массива int (целочисленный массив) от имени переменной.
Инициализаторы массивов и безымянные массивы
В языке Java есть средство для одновременного создания массива и его инициализации. Вот пример такой синтаксической конструкции:
int smallPrimes = { 2, 3, 5, 7, 11, 13};
Отметим, что в этом случае не нужно применять оператор new. Кроме того, можно даже инициализировать безымянный массив:
new int { 16, 19, 23 , 29 , 31, 37}
Это выражение выделяет память для нового массива и заполняет его числами, указанными в фигурных скобках. При этом подсчитывается их количество и, соответственно, определяется размер массива. Эту синтаксическую конструкцию удобно применять для повторной инициализации массива без образования новой переменной. Например, выражение
smallPrimes = new int{ 17, 19, 23, 29, 31, 37 };
представляет собой укороченную запись выражения
int anonymous = { 17, 19, 23, 29, 31, 37 };
smailPrimes = anonymous;
Можно создать массив нулевого размера. Такой массив может оказаться полезным при написании метода, вычисляющего некий массив, который оказывается пустым. Массив нулевой длины объявляется следующим образом:
new типЭлементов
Заметим, что такой массив не эквивалентен объекту null.
Копирование массивов
Один массив можно скопировать в другой, но при этом обе переменные будут ссылаться на один и тот же массив.
int luckyNumbers = smailPrimes;
luckyNuimbers = 12; // Теперь элемент smailPrimesтакже равен 12.
Результат показан на рис. 3.14. Если необходимо скопировать все элементы одного массива в другой, следует использовать метод arraycopy из класса System. Его вызов выглядит следующим образом:
System.arraycopy(from, fromlndex, to, tolndex, count);
Массив to должен иметь достаточный размер, чтобы в нем поместились все копируемые элементы.
Рис. 3.14. Копирование массива
Например, показанные ниже операторы, результаты работы которых изображены на рис. 3.15, создают два массива, а затем копируют последние четыре элемента первого массива во второй. Копирование начинается со второй позиции в исходном массиве, а копируемые элементы помещаются в целевой массив, начиная с третьей позиции.
int smailPrimes = {2, 3, 5, 7, 11, 13};
int luckyNumbers = {1001, 1002, 1003, 1004, 1005, 1006, 1007};
System.аггаусору(smailPrimes, 2, luckyNumbers, 3, 4);
for (int i = 0; i < luckyNumbers.length; i++)
System.println(i +.": " + luckyNumbersfi]);
Выполнение этих операторов приводит к следующему результату.
0: 1001
1: 1002
2: 1003
3: 5
4: 7
5: 11
6: 13
Рис. 3.15. Копирование элементов массива
Массив в языке Java значительно отличается от массива в языке C++. Однако он практически совпадает с указателем на динамический массив. Это значит, что оператор
int a = new int; //Java
эквивалентен оператору
i n t * = new i n t [ 1 0 0 ] ; // C++,
а не
int a; // C++
В языке Java оператор no умолчанию проверяет диапазон изменения индексов. Кроме того, в языке Java нет арифметики указателей - нельзя увеличить указатель а, чтобы обратиться к следующему элементу массива.
Это специальная структура, существующая практически в каждом языке программирования, позволяющая описывать группу однотипных объектов, используя общее имя.
Представим, что у вас есть приют для бездомных животных, в котором пять котов. Как зовут каждого вы не помните, но у каждого есть жетончик с номерком, который позволяет идентифицировать каждое животное. Можно сказать, что это и есть массив "котики" размером пять. Обратите внимание, на то что индексация начинается с нуля - так принято в Java. Если бы не было возможности создавать массивы, нужно было бы объявлять пять переменных и придумывать им имена, что не очень удобно.
В Java можно создавать массивы любой размерности - одномерные, двумерные, трехмерные и т.д. Начнем с простейшего варианта - с одномерных массивов.
Одномерные массивы представляют собой список однотипных переменных. Чтобы создать массив, нужно сначала объявить переменную массива требуемого типа. Общая форма объявления одномерного массива выглядит следующим образом:
Тип имяПеременной;
где параметр тип обозначает тип элемента массива, называемый также базовым типом.
Квадратные скобки можно ставить перед переменной или после нее. Но более правильным вариантом считается указание скобок перед переменной - таким образом тип и скобки находятся в одном месте, что позволяет с первого взгляда понять, что перед вами массив такого-то типа.
Int monthDays; double monthSalaries;
Когда массив объявлен, память под него еще не выделена. Для выделение памяти под массив используется ключевое слово new, после которого опять указывается тип массива и в квадратных скобках - размер:
ИмяПеременной = new тип[размер];
Массив может быть объявлен и инициализирован одной строкой:
Int values = new int;
Рассмотрим пример объявления массива типа int размером 12 на данном примере. После выполнения строки int monthDays = new int массив из 12 элементов создан. Каждому элементу присваивается значение по умолчанию для заданного типа. Для типа int это ноль. Для обращения к отдельному элементу массива после имени массива в квадратных скобочках задаем индекс элемента. Таким образом мы можем обратиться к элементу массива для изменения или получения его значения.
Public class Array1 { public static void main(String args) { int monthDays = new int; monthDays = 31; monthDays = 28; monthDays = 31; monthDays = 30; monthDays = 31; monthDays = 30; monthDays = 31; monthDays = 31; monthDays = 30; monthDays = 31; monthDays = 30; monthDays = 31; System.out.println("B апреле " + monthDays + " дней."); } }
Если заранее известны значения для каждого элемента массива, можно использовать блок для инициализации массива. Вместо new int, в фигурных скобках через запятую перечисляются значения элементов массива. Размер массива выводится компилятором из количества указанных элементов.
Public class Array2 { public static void main(String args) { int monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; System.out.println("B апреле " + monthDays + " дней."); } }
Существует еще и третья форма объявления массива - безымянный массив. Он может использоваться в двух случаях. Первый - вы объявили и инициализировали массив testScores размера четыре, но потом по какой-то причине он должен быть изменен - он должен содержать три элемента. Использовать повторно форму для инициализации массива нельзя - будет ошибка компиляции:
Int testScores = {1, 2, 3, 4}; ... testScores = {4, 7, 2}; //ошибка компиляции
Но можно использовать безымянный массив, который создаст новый массив в памяти. Форма написания безымянного массива - это микс первых двух:
TestScores = new int{4, 7, 2};
Второй случай использования безымянного массива - это передача массива в метод. В следующем примере метод print принимает на входа массив типа int. При вызове метода в качестве аргумента можно передать безымянный массив.
Многомерные массивы представляют собой массивы массивов.
При объявлении переменной многомерного массива для указания каждого дополнительного индекса используется отдельный ряд квадратных скобок. Например:
Int twoD = new int;
Следующий рисунок показывает как можно визуально представить двумерный массив 4 на 5. Левый индекс определяет строку, а правый столбец.
Следующий пример демонстрирует каким образом можно установить значения в двухмерный массив 4x5. Для перебора строк используется внешний цикл for , для перебора столбцов - внутренний. Каждому следующему элементу присваивается значение на единицу большее чем предыдущее.
Public class TwoDArray1 { public static void main(String args) { int twoD = new int; int i, j, k = 0; for (i = 0; i < 4; i++) { for (j = 0; j < 5; j++) { twoD[i][j] = k++; System.out.print(twoD[i][j] + " "); } System.out.println(); } } }
Рассмотрим теперь как представлен массив int twoD = new int; в памяти.Переменная twoD указывает не на матрицу, а на строку (красного цвета) состоящую из трех элементов. Значение каждого элемента - это ссылка на строку из четырех элементов (фиолетового цвета).
Следующая картинка показывает каким образом хранится трехмерный массив int threeD = new int в памяти:
Подобным образом может храниться массив любой размерности в памяти.
В двухмерных массивах, которые мы рассматривали до сих пор, количество элементов в каждой строке одинаково - чаще всего так и бывает. Но это не обязательно, каждая строка может содержать разное количество элементов. Например:
Посмотрим код, реализующий такой массив. При объявлении массива необходимо задать количество элементов только для первой размерности - int array = new int . Таким образом, мы указываем количество строк в массиве, но под каждую строку память не выделяем. Далее выделяем отдельно память под каждую строку массива. Например, строка с индексом ноль будет размера 1 - array = new int.
Public class TwoDArray2 { public static void main(String args) { int array = new int; array = new int; array = new int; array = new int; array = new int; int i, j, k = 0; for (i = 0; i < 4; i++) { for (j = 0; j < i + 1; j++) { array[i][j] = k++; System.out.print(array[i][j] + " "); } System.out.println(); } } }
Для многомерных массивов можно также использовать блок для инициализации, если значения всех элементов заранее известны. Каждая отдельная строка заключается в фигурные скобки:
Public class TwoDArray3 { public static void main(String args) { double arrayTwoD = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15} }; for (double arrayOneD: arrayTwoD) { for (double element: arrayOneD) { System.out.print(element + " "); } System.out.println(); } } }
Следующий пример демонстрирует как получать длину массива. Для этого используется переменная length . С одномерным массивом все понятно - его длина это количество его элементов. Длина многомерного массива - это количество элементов его первой размерности. Например, длина массива array2 - это 2. Также можно получить длину каждой строки массива. Например, array2.length - вернет количество элементов в строке с индексом ноль.
Public class ArraySize { public static void main(String args) { int array1 = {1, 2, 3, 4}; int array2 = {{1, 1, 1}, {2, 2, 2}}; System.out.println("Размер массива array1 = " + array1.length); System.out.println("Размер массива array2 = " + array2.length); System.out.println("Размер 1-строки массива array2 = " + array2.length); } }
Результат выполнения:
Размер массива array1 = 4 Размер массива array2 = 2 Размер 1-строки массива array2 = 3
Существует ряд методов, полезных при работе с массивами. Рассмотрим их:
Метод возвращает строковое представление одномерного массива, разделяя элементы запятой. Вместо того, чтобы перебирать массивы циклом for , как мы делали в примере 4, можно воспользоваться этим методом для вывода элементов на консоль:
Метод возвращает строковое представление многомерного массива, выделяя строки квадратными скобками:
Метод Arrays.sort() сортирует элементы числового массива по возрастанию:
Метод Arrays.binarySearch() ищет в массиве заданное значение и возвращает номер элемента. Если искомый элемент не найден, то возвращается -(position + 1) , где position - позиция элемента где он МОГ БЫ БЫТЬ. Массив должен быть отсортирован, иначе результат вызова метода будет неопределен:
Результат выполнения:
Метод System.arraycopy() позволяет копировать часть массива в другой массив.
Рассмотрим пример, копирующий элементы 2,3,4 из массива arraySource в массив arrayDestination:
Import java.util.Arrays; public class ArrayCopy1 { public static void main(String args) { int arraySource = {1, 2, 3, 4, 5, 6}; int arrayDestination = {0, 0, 0, 0, 0, 0, 0, 0}; System.out.println("arraySource: " + Arrays.toString(arraySource)); System.out.println("arrayDestination: " + Arrays.toString(arrayDestination)); System.arraycopy(arraySource, 1, arrayDestination, 2, 3); System.out.println("arrayDestination after arrayCopy: " + Arrays.toString(arrayDestination)); } }
Результат выполнения:
ArraySource: arrayDestination: arrayDestination after arrayCopy:
Можно копировать в тот же массив с перекрытием областей:
Import java.util.Arrays; public class ArrayCopy2 { public static void main(String args) { int array = {1, 2, 3, 4, 5, 6, 7, 8}; System.out.println(Arrays.toString(array)); System.arraycopy(array, 1, array, 3, 3); System.out.println(Arrays.toString(array)); } }
Результат выполнения:
Массив – это набор однотипных переменных, на которые ссылаются по общему имени. Массивы можно создавать из элементов любого типа, и они могут иметь одно или несколько измерений. К определенному элементу в массиве обращаются по его индексу (номеру). В заметке мы рассмотрим обработку одномерных и двумерных массивов.
Одномерный массив – это, по существу, список однотипных переменных. Чтобы создать массив, сначала следует создать переменную массива (array variable) желательного типа. Общий формат объявления одномерного массива:
type var-name ;
Здесь type объявляет базовый тип массива; var-name – имя переменной массива. Базовый тип определяет тип данных каждого элемента массива. Например, объявление одномерного массива int-компонентов с именем month_days имеет вид:
int month_days ;
Хотя это объявление и устанавливает факт, что month_days является переменной массива, никакой массив в действительности не существует. Фактически, значение month_days установлено в null (пустой указатель), который представляет массив без значения. Чтобы связать month_days с фактическим, физическим массивом целых чисел, нужно выделить память для него, используя операцию new , и назначать ее массиву month_days ; new – это специальная операция, которая распределяет память.
Общий формат new в применении к одномерным массивам имеет вид:
array-var = new type ;
где type – тип распределяемых данных, size – число элементов в массиве, array-var– переменная, которая связана с массивом. Чтобы использовать new для распределения памяти под массив, нужно специфицировать тип и число элементов массива. Элементы в массиве, выделенные операцией new , будут автоматически инициализированы нулями. Следующий пример распределяет память для 12-элементного массива целых чисел и связывает его с переменной month_days .
month_days = new int;
После того как эта инструкция выполнится, month_days будет ссылаться на массив из двенадцати целых чисел. Затем все элементы в массиве будут инициализированы нулями.
Процесс получения массива включает два шага. Во-первых, следует объявить переменную массива желательного типа. Во-вторых, необходимо выделить память, которая будет содержать массив, используя операцию new , и назначать ее переменной массива. Таким образом, в Java
все массивы являются динамически распределяемыми.
Как только вы выделили память для массива, можно обращаться к определенному элементу в нем, указывая в квадратных скобках индекс. Нумерация элементов массива начинается с нуля. Имена массивов являются ссылками.
Возможна комбинация объявления переменной типа массив с выделением массиву памяти непосредственно в объявлении:
int month_days = new int;
Рассмотрим код программы, выполняющей замену отрицательных элементов массива на максимальный элемент:
Public class FindReplace { public static void main(String args) { int myArray; // объявление без инициализации int mySecond = new int; /* выделение памяти с инициализацией значениями по умолчанию */ int a = {5, 10, 0, -5, 16, -2}; // объявление с инициализацией int max = a; for (int i = 0; i < a.length; i++) { if (a[i]<0) a[i] = max; mySecond[i] = a[i]; System.out.println("a[" + i + "]=" + a[i]); } myArray = a; // установка ссылки на массив a } }
В результате выполнения будет выведено:
>java FindReplace a=5 a=10 a=0 a=5 a=16 a=5
Присваивание mySecond[i] = a[i] приведет к тому, что части элементов массива mySecond , а именно шести, будут присвоены значения элементов массива a . Остальные элементы mySecond сохранят значения, полученные при инициализации, то есть нули. Если же присваивание организовать в виде mySecond = a или myArray = a , то оба массива участвующие в присваивании получат ссылку на массив a , то есть оба будут содержать по шесть элементов и ссылаться на один и тот же участок памяти.
Массивы можно инициализировать во время их объявления. Процесс во многом аналогичен тому, что используется при инициализации простых типов. Инициализатор массива – это список разделенных запятыми выражений, окруженный фигурными скобками. Массив будет автоматически создаваться достаточно большим, чтобы содержать столько элементов, сколько вы определяете в инициализаторе массива. Нет необходимости использовать операцию new . Например, чтобы хранить число дней в каждом месяце, следующий код создает инициализированный массив целых чисел:
Public class MonthDays { public static void main(String args) { int month_days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; System.out.println("Апрель содержит " + month_days + " дней."); } }
В результате выполнения программы на экран будет выведено:
Апрель содержит 30 дней.
Замечание: Java делает строгие проверки, чтобы удостовериться, что вы случайно не пробуете сохранять или читать значения вне области хранения массива. Исполнительная система Java тоже делает тщательные проверки, чтобы убедиться, что все индексы массивов находятся в правильном диапазоне. (В этом отношении Java существенно отличается от языков C/C++ , которые не обеспечивают проверки границ во время выполнения).
В Java многомерные массивы
– это, фактически, массивы массивов. Они выглядят и действуют подобно регулярным многомерным массивам. Однако имеется пара тонких различий. Чтобы объявить многомерную переменную массива, определите каждый дополнительный индекс, используя другой набор квадратных скобок. Например, следующее утверждение объявляет переменную двумерного массива с именем twoD:
int twoD = new int;
Оно распределяет память для массива 4x5 и назначает ее переменной twoD . Внутренне эта матрица реализована как массив массивов целых чисел тип int .
Многомерные массивы возможно инициализировать. Для этого просто включают инициализатор каждого измерения в его собственный набор фигурных скобок.
В следующей программе создаются и инициализируются массивы массивов равной длины (матрицы), и выполняется произведение одной матрицы на другую:
Public class Matrix { private int a; Matrix(int n, int m) { // создание и заполнение с random a = new int[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) a[i][j] = (int) (Math.random()*5); show(); } public Matrix(int n, int m, int k) { // создание и заполнение с random a = new int[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) a[i][j] = k; if (k != 0) show(); } public void show() { System.out.println("Матрица:" + a.length + " на " + a.length); for (int i = 0; i < a.length; ++i) { for (int j = 0; j < a.length; ++j) System.out.print(a[i][j] + " "); System.out.println(); } } public static void main(String args) { int n = 2, m = 3, z = 4; Matrix p = new Matrix(n, m); Matrix q = new Matrix(m, z); Matrix r = new Matrix(n, z, 0); for (int i = 0; i < p.a.length; ++i) for (int j = 0; j < q.a.length; ++j) for (int k = 0; k < p.a[i].length; ++k) r.a[i][j] += p.a[i][k]*q.a[k][j]; System.out.println("Произведение матриц: "); r.show(); } }
Так как значения элементам массивов присваиваются при помощи метода random() , то одним и вариантов выполнения кода может быть следующий:
> javac Matrix.java > java Matrix Матрица:2 на 3 3 2 0 3 3 1 Матрица:3 на 4 1 2 2 3 3 2 3 2 1 2 3 2 Произведение матриц: Матрица:2 на 4 9 10 12 13 13 14 18 17
Следующий пример демонстрирует копирование массива:
Public class ArrayCopyDemo { public static void main(String args) { int mas1 = {1,2,3}, mas2 = {4,5,6,7,8,9}; System.out.print("mas1: "); show(mas1); System.out.print("mas2: "); show(mas2); // копирование массива mas1 в mas2 System.arraycopy(mas1, 0, mas2, 2, 3); /* 0 - mas1 копируется начиная с нулевого элемента * 2 - элемент, с которого начинается замена * 3 - количество копируемых элементов */ System.out.println("\n после arraycopy(): "); System.out.print("mas1: "); show(mas1); System.out.print("\nmas2: "); show(mas2); } private static void show(int mas) { for (int i = 0; i < mas.length; ++i) System.out.print(" " + mas[i]); } }
Результат выполнения программы:
> javac ArrayCopyDemo.java > java ArrayCopyDemo mas1: 1 2 3mas2: 4 5 6 7 8 9 после arraycopy(): mas1: 1 2 3 mas2: 4 5 1 2 3 9
Существует иная форма, которая может использоваться для объявления массива:
type var-name;
Здесь квадратные скобки следуют за спецификатором типа, а не именем переменной массива. Например, следующие два объявления эквивалентны:
Int al = new int;
int a2 = new int;
Представленные здесь объявления также эквивалентны:
char twodi = new char;
char twod2 = new char;
Эта альтернативная форма объявления включена, главным образом, для удобства.
Массивы (arrays) _ это упорядоченные наборы элементов одного типа. Элементами массива могут служить объекты простых и ссылочных типов, в том Числе и ссылки на другие массивы. Массивы сами по себе являются объектами и
наследуют класс Object. Объявление
int ia = new int;
Определяет массив с именем ia, который изначально указывает на набор из трех Элементов типа int.
В объявлении массива его размерность не указывается. Количество элементов массива задается при его создании посредством оператора new. Длина массива фиксируется в момент создания и в дальнейшем изменению не поддается. Впрочем, переменной типа массива (в нашем примере – ia) в любой момент может быть поставлен в соответствие новый массив с другой размерностью.
Доступ к элементам массива осуществляется по значениям их номеров-индексов.
Первый элемент массива имеет индекс, равный нулю (0), а последний – length – 1. Обращение к элементу массива выполняется посредством задания имени массива и значения индекса, заключенного в квадратные скобки, [ и ]. в предыдущем примере первым элементом массива ia будет ia, а последним – ia. При каждом обращении к элементу массива по индексу исполняющая система Java проверяет, находится ли значение индекса в допустимых пределах, и генерирует исключение типа ArraylndexOutOfBoundsException, если результат проверки ложен. 6 Выражение индекса должно относиться к типу int – только этим и ограничивается максимальное количество элементов массива.
Длину массива легко определить с помощью поля length объекта массива (которое неявно снабжено признаками publiс и final). Ниже приведен дополненный код прежнего примера, в котором предусмотрено выполнение Цикла, обеспечивающего вывод на экран содержимого каждого элемента массива ia:
for (int i = о; i < ia.length; i++)
system.out.println(i + ": " + ia[i]);
Массив нулевой длины (т.е. такой, в котором нет элементов) принято называть пустым. Обратите внимание, что ссылка на массив, равная значению null, и ссылка на пустой массив – это совершенно разные вещи. Пустой массив это реальный массив, в котором попросту отсутствуют элементы. Пустой массив представляет собой удобную альтернативу значению null при возврате из метода. Если метод способен возвращать null, прикладной код, в котором выполняется обращение к методу, должен сравнить возвращенное значение с null прежде, чем перейти к выполнению оставшихся операций. Если же метод возвращает массив (возможно, пустой), никакие дополнительные проверки не нужны – разумеется, помимо тех, которые касаются длины массива и должны выполняться в любом случае.
Допускается и иная форма объявления массива, в которой квадратные скобки задаются после идентификатора массива, а не после наименования его типа:
int ia = new int;
Прежний синтаксис, однако, считается более предпочтительным, поскольку описание типа в таком случае выглядит более компактным.
Модификаторы в объявлениях массивов
Правила употребления в объявлениях массивов тех или иных модификаторов обычны и зависят только от того, к какой категории относится массив – к полям или Локальным переменным. Существует единственная особенность, которую важно помнить, – модификаторы применяются к массиву как таковому, но не к его отдельным элементам. Если в объявлении массива указан признак final, это значит только то, что ссылка на массив не может быть изменена после его создания, но никак не запрещает возможность изменения содержимого отдельных элементов массива. Язык не позволяет задавать каких бы то ни было модификаторов (скажем, final или уоlatilе) для элементов массива.
Многомерные массивы
В Java поддерживается возможность объявления многомерных массивов (multidimensional arrays) (т.е. массивов, элементами которых служат другие массивы), Код, предусматривающий объявление двумерной матрицы и вывод на экран содержимого ее элементов, может выглядеть, например, так:
float mat = new float;
setupMatrix(mat);
for (int у = о; у < mat.length; у++) {
for (int х = о; х < mat[y].length; х++)
system.out.print(mat[y][x] + " ");
system.out.println();
При создании массива должна быть указана, по меньшей мере, его первая, "самая левая", размерность. Другие размерности разрешается не задавать – в этом случае их придется определить позже. Указание в операторе new единовременно всех размерностей – это самый лаконичный способ создания массива, позволяющий избежать необходимости использования дополнительных операторов new. Выражение объявления и создания массива mat, приведенное выше, равнозначно следующему фрагменту кода:
float mat = new float;
for (int у = о; у < mat.length; у++)
mat[y] = new float;
Такая форма объявления обладает тем преимуществом, что позволяет наряду с получением массивов с одинаковыми размерностями (скажем, 4 х 4) строить и массивы массивов различных размерностей, необходимых для хранения тех или иных последовательностей данных.
Инициализация массивов
При создании массива каждый его элемент получает значение, предусмотренное по умолчанию и зависящее от типа массива: нуль (0) – для числовых типов, ‘\u0000′ _ для char, false – для boolean и null – для ссылочных типов. Объявляя массив ссылочного типа, мы на самом деле определяем массив переменных этого типа. Рассмотрим следующий фрагмент кода:
Attr attrs = new Attr;
for (int i = о; i < attrs.length; i++)
attrs[i] = new Attr(names[i], values[i]);
После выполнения первого выражения, содержащего оператор new, переменная attrs получит ссылку на массив из 12 переменных, которые инициализированы значением null, Объекты Attr как таковые будут созданы только в процессе про хождения цикла.
Массив может инициализироваться (одновременно с объявлением) посредством конструкции в фигурных скобках, в которой перечислены исходные Значения его элементов:
String dangers = { "Львы", "Тигры", "Медведи" };
Следующий фрагмент кода даст тот же результат:
String dangers = new String; dangers = "Львы";
dangers = "Тигры";
dangers = "Медведи";
Первая форма, предусматривающая задание списка инициализаторов в фигурных скобках, не требует явного использования оператора new – он вызывается косвенно исполняющей системой. Длина массива в этом случае определяется Количеством значений-инициализаторов. Допускается и возможность явного задания оператора new, но размерность все равно следует опускать она, как и раньше, определяется исполняющей системой:
String dangers = new String { "Львы", "Тигры", "Медведи" };
Подобную форму объявления и инициализации массива разрешается применять в любом месте кода, например в выражении вызова метода:
printStringsCnew String { "раз", "два", "три" });
Массив без названия, который создается таким образом, называют анонимным (anonymous).
Массивы массивов могут инициализироваться посредством вложенных последовательностей исходных значений. Ниже приведен пример объявления массива, содержащего несколько первых строк так называемого треугольника Паскаля, где каждая строка описана собственным массивом значений.
int pascalsTriangle = {
{ 1, 4, 6, 4, 1 },
Индексы многомерных массивов следуют в порядке от внешнего к внутренним. Так, например, pascalsTriangle}