В принципе, один массив может быть присвоен в качестве значения другому массиву, если их типы совпадают. Массивы также можно сравнивать. Правда, все означенные операции выполняются довольно специфически и в некоторой степени могут удивить. Чтобы свести такое удивление к минимуму, имеет смысл еще раз остановиться на том, что же такое массив и как его техническая реали- зация связана синтаксическими конструкциями языка Java.
Напомним наиболее существенные моменты, связанные с объявлением масси- вов в Java.
Переменная, обозначающая массив (переменная массива), объявляется незави- симо от фактического выделения памяти под массив. Другими словами, непо- средственно массив и переменная массива — это далеко не одно и то же. В этом смысле показательным является двухэтапный (двумя командами) процесс со- здания массива. Например:
int[] nums;
nums=new int[]{1,2,3,4};
В данном случае команда int[] nums есть не что иное, как объявление перемен- ной nums. Тип этой переменной — «массив целых чисел». Значением перемен- ной может быть ссылка (адрес) на какой-нибудь массив, состоящий из целых чисел.
Оператор new в общем случае служит для динамического выделения памяти под различные объекты, в том числе массивы. Командой new int[]{1,2,3,4} в памяти выделяется место для целочисленного массива из четырех элементов, соответствующие значения присваиваются элементам массива. У этого вновь созданного массива есть адрес (ссылка на массив). В качестве значения опера- тор new возвращает ссылку на созданный объект. В данном случае возвраща- ется ссылка на массив. Эта ссылка в качестве значения присваивается пере-
менной nums. Теперь несложно догадаться, каким будет результат выполнения следующих команд:
Все достаточно просто. Первой командой int[] nums,data объявляются две пере- менные массива nums и data. Второй командой nums=new int[]{1,2,3,4} создается массив, а ссылка на него присваивается в качестве значения переменной nums. Далее командой data=nums значение переменной nums присваивается переменной data. Однако значение переменой nums — это ссылка на массив. Поэтому после присваивания переменная data ссылается на тот же массив! Например, элемент data[1] имеет такое же значение, что и nums[1] (значение 2). Точнее, это один и тот же элемент. Более того, если теперь изменить какой-нибудь элемент мас- сива data (например, data[3]=-1), автоматически изменится и соответствующий элемент массива nums. Причина та же — массив на самом деле один, просто на него ссылаются две переменные.
При сравнении массивов с помощью операторов равно == и не равно != (на- пример, nums==data или nums!=data) сравниваются значения переменных массива, а не элементы в этих массивах. Поэтому результатом выражения nums==data яв- ляется true, если обе переменные массива nums и data ссылаются на один и тот же массив.
Пример программы, в которой имеет место присваивание массива, приведен в листинге 3.7.
В программе объявляются два целочисленных массива: массив nums из 10 эле- ментов и массив data из 20 элементов. С помощью инструкции цикла эти мас- сивы заполняются: массив nums заполняется нечетными числами, массив data — четными. После этого командой data=nums массиву data в качестве значения присваивается массив nums. Обращаем внимание, что хотя эти массивы имеют
одинаковый тип, у них разные размеры. Далее с помощью еще одной инструк- ции цикла элементы массива data выводятся с интервалом в одну строку (для вывода значений без перехода к новой строке используем метод print()). В ре- зультате мы получаем числовой ряд:
1 3 5 7 9 11 13 15 17 19
Это те значения, которыми инициализировался массив nums. Интерес в данном случае представляет то обстоятельство, что в инструкции цикла, обеспечиваю- щей вывод значений массива data, верхняя граница для индексов элементов массива определяется через свойство length массива data. Массив инициализи- ровался с размером 20, а в конечном итоге его размер оказался равным 10! При- чина очевидна. После выполнения команды data=nums переменная массива data начинает ссылаться на тот же массив, что и переменная массива nums.
Особенности сравнения массивов на предмет равенства (неравенства) иллю- стрируются программным кодом листинга 3.8.
Листинг 3.8.Сравнение массивов
class MyArrayDemo2{
public static void main(String[] args){
// Объявление массивов:
int[] nums=new int[]{1,2,3,4,5};
int[] data=new int[]{1,2,3,4,5};
// Комментирование следующей команды можно отменить:
Программа предназначена для сравнения двух целочисленных массивов. В про- грамме объявляются два целочисленных массива nums и data и инициализиру- ются одинаковыми наборами значений. Далее непосредственно выполняется проверка. Состоит она из трех этапов. Сначала выполняется проверка равенства переменных массивов nums и data. Если ссылки равны, то, очевидно, массивы одинаковы (совпадают). Проверка равенства ссылок на массивы выполняется
с помощью условной инструкции if() с условием data==nums. При выполненном условии выводится сообщение Совпадающие массивы!. При этом работа программы завершается, для чего используется команда return.
Если ссылки различны, выполняется поэлементная проверка массивов. Мас- сивы считаются одинаковыми, если у них совпадают соответствующие эле- менты. Но прежде необходимо проверить, совпадают ли размеры массивов. Проверка равенства размеров массивов также выполняется с помощью услов- ной инструкции if(), при этом проверяется условие data.length!=nums.length. Условие является истинным, если массивы имеют разные размеры. В этом случае выводится сообщение Несовпадающие элементы!, и работа программы за- вершается.
При совпадающих размерах массивов запускается цикл, в рамках которого срав- ниваются элементы двух массивов. Для этого использована условная инструк- ция if() с проверяемым условием data[i]!=nums[i] (i — индексная переменная). Если встречаются несовпадающие элементы, выводится сообщение Несовпадаю- щие элементы!, и работа программы завершается.
В случае если два массива имеют только совпадающие элементы, цикл закан- чивается без последствий, и, самое главное, работа программы продолжается, поэтому в конце выводится сообщение Одинаковые массивы!.
В данном случае для списков инициализации массивов, приведенных в листин- ге 3.8, в результате выполнения программы появляется сообщение Одинаковые массивы!. Программа содержит закомментированную команду data=nums. Если отменить комментирование, результатом будет сообщение Совпадающие массивы!. Чтобы увидеть прочие сообщения, следует, не отменяя комментирование, вне- сти изменения в списки инициализации массивов.