— Амиго, я надеюсь, ты уже понял, насколько полезны массивы в программировании?
— Естественно, Риша! Не одну задачу уже решил.
— А в твоих задачах были повторяющиеся действия? Такие, которые ты проделывал снова и снова.
— Если я тебя правильно понял, ты имеешь в виду похожие действия в разных задачах? Ну вот, например, везде вывод массива через цикл — прямо надоело это делать!
— Да, я именно об этом. Вот и создатели Java заметили, что Java-программисты часто пишут один и тот же код при работе с массивами. Например, «скопировать часть массива в другой массив», «заполнить все ячейки массива одинаковыми значениями». Или твой пример: «вывести содержимое массива в удобно читаемом виде на экран».
— А у настоящих программистов есть одно очень важное правило: «не повторяйся». Согласись, неправильно делать лишнюю работу, за неё тебе не заплатят. Платят за эффективную, уж поверь. Кстати, код зелёного новичка сразу узнают по большому количеству повторов.
— Подумали создатели Java, и разработали специальный класс – Arrays
(полное имя java.util.Arrays
), в который поместили самые популярные действия при работе с массивами.
— Хм… Интересно-интересно. И что же в нём такого?
— В нем очень много методов на все случаи жизни, но для начала мы рассмотрим только 10 из них — самые простые и часто используемые.
Метод Arrays.toString()
— Первый метод, который мы рассмотрим, называется Arrays.toString()
. Но для начала немного предыстории.
— У каждого массива в Java есть метод toString()
, который возвращает «текстовое представление массива». Получить текстовое представление массива можно с помощью такой конструкции:
String str = имя.toString();
— Где имя
— это имя переменной-массива, а str
— это имя переменной, в которую сохранится строковое представление массива. Амиго, ты небось уже пробовал вывести на экран массив с помощью метода System.out.println(имя)
?
— Каюсь, было дело. Увидел какие-то крякозябры, и решил, от греха подальше, продолжить пользоваться циклами.
— Скорее всего ты увидел что-то вроде:
I@37afeb11
— Первая буква I
означает, что это массив типа int
, а символы после @
– адрес одного объекта в памяти. Можно считать, что это — адрес массива в памяти. С одной стороны, переменная-массив именно эту информацию и хранит, а с другой — ты ожидал чего-то другого, не так ли?
— Именно! Я планировал увидеть значения, которые есть в массиве, а не вот это всё.
— Для того, чтобы увидеть именно значения массива, и придумали метод Arrays.toString()
. Его вызов выглядит так:
String str = Arrays.toString(имя);
Примеры:
|
Переменная str будет содержать строковое значение
"[1, 2, 3]" |
|
Переменная str будет содержать строковое значение
"[]" |
|
Переменная str будет содержать строковое значение
"[Привет, Как, Дела]" |
Метод Arrays.deepToString()
— Однако метода toString()
не хватит, если речь идёт о двумерных массивах. То есть если ты попробуешь вызвать Arrays.toString()
, то увидишь кое-что знакомое:
[I@37afeb11, I@37afeb21, I@37afeb31]
— А все дело в том, что в ячейках двумерного массива хранятся ссылки на одномерные массивы. А одномерные массивы как преобразовываются в строку? Именно так, как ты видишь выше.
— Что же делать тогда? Как нам получить правильное отображение двумерного массива?
— Творцы Java и это предусмотрели. Для этого у класса Arrays
есть еще один специальный метод — deepToString()
. Вызов его выглядит так:
String str = Arrays.deepToString(имя);
— В этот метод можно передать двумерный, одномерный, трехмерный и вообще массив любой размерности, и он всегда будет отображать элементы массива.
Примеры:
|
Переменная str будет содержать строковое значение
"[1, 2, 3]" |
|
Переменная str будет содержать строковое значение
"[[1, 1], [2, 2], [3, 3]]" |
|
Переменная str будет содержать строковое значение
"[[[1, 2, 3], [1]], [[]]]" |
Метод Arrays.equals()
— С выводом массивов на экран разобрались. А что насчет сравнения массивов? Ты помнишь, какие методы мы можем использовать для сравнения строк?
— Я обычно использую метод equals
!
— Да, equals
, и ещё equalsIgnoreCase
(который сравнивает строки независимо от строчных и прописных букв).
— Хорошая новость: для массивов тоже можно использовать метод equals
. Плохая новость: он не сравнивает содержимое массивов. Метод equals
у массивов делает то же самое, что и оператор ==
– сравнивает ссылки.
Примеры:
|
false (ссылки не равны) |
|
Метод equals у массивов банально сравнивает ссылки двух массивов.false (ссылки не равны) |
— И что же делать? Как сравнить массивы по их содержанию?
— И опять нам на выручку приходит класс Arrays
. Вернее, его метод Arrays.equals()
Выглядит его вызов так:
Arrays.equals(имя1, имя2)
— Метод возвращает true
(истина), если массивы равной длинны и их элементы равны. Иначе возвращает false
(ложь).
Примеры:
|
Метод equals у массивов банально сравнивает ссылки двух массивов.false (ссылки не равны) |
|
true (содержимое массивов равно) |
|
false (содержимое массивов отличается) |
Метод Arrays.deepEquals()
— И, как ты уже, наверное, догадываешься, метод Arrays.equals
для двумерных массивов будет работать неправильно: он работает с двумерным массивом как с одномерным, элементы которого — адреса одномерных массивов.
— Поэтому, чтобы правильно сравнивать многомерные массивы (n=1, 2, 3, ...
), придумали метод Arrays.deepEquals()
. Выглядит его вызов так:
Arrays.deepEquals(имя1, имя2)
— Метод возвращает true
(истина), если массивы равной длины и их элементы равны. Иначе возвращает false
(ложь). Если элементы внутри массива — тоже массивы, для их сравнения используется метод Arrays.deepEquals()
и так далее.
Примеры:
|
Метод equals у массивов банально сравнивает ссылки двух массивов.false (ссылки не равны) |
|
Метод Arrays.equals сравнит x1 и x2 как одномерные массивы, которые хранят ссылки. Ссылки в них хранятся разные.false (содержимое массивов неравно) |
|
true (содержимое массивов равно) |
— Спасибо, Риша! Это та самая лекция, которая сделает мою жизнь проще и приятнее в будущем. Теперь буду пользоваться методами класса Arrays и быстрее писать программы.
— На это я и рассчитывал, хе-хе. Но это ещё не все интересные методы класса Arrays. О других я расскажу тебе в следующий раз.