И снова привет! :) На прошлом занятии мы познакомились с такой структурой данных как массив (Java array), научились создавать массивы, наполнять данными, а также узнали, как они хранятся в памяти.
Коротко: класс
Идею мы придумали, осталось только написать код. Выглядеть он будет так:
В будущем ты еще не раз увидишь (и порадуешься этому), что создатели Java предусмотрели очень много типовых ситуаций, с которыми сталкиваются программисты при работе, и реализовали в языке готовые решения для них. Использовать эти решения гораздо проще и удобнее, чем изобретать велосипеды, верно? :)
Обязательно почитай документацию класса
Arrays (java.util.Arrays) содержит готовые методы для типовых операций с массивами: сортировки (sort), вывода на экран (toString), копирования (copyOf, copyOfRange) и сравнения по содержимому (equals). Он избавляет от написания ручных циклов для рутинных задач.
Сегодня мы рассмотрим некоторые задачи и примеры работы с массивами, которые часто будут встречаться тебе в реальной работе.
Кратко
- Класс
Arrays(java.util.Arrays) содержит готовые методы для типовых операций с массивами. Arrays.sort()сортирует массив,Arrays.toString()выводит его в читаемом виде.Arrays.copyOf()копирует массив (целиком или первые N элементов),Arrays.copyOfRange()копирует часть по диапазону.Arrays.equals()сравнивает массивы по содержимому (обычный==иObject.equals()сравнивают ссылки).- Для двумерных массивов есть
Arrays.deepEquals()иArrays.deepToString(). - Главная идея: не изобретать велосипед, а использовать готовые методы вместо ручных циклов.
//array Java, example
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Наша задача состоит в том, чтобы отсортировать этот массив по возрастанию: от меньших чисел к большим.
В итоге он должен выглядеть так:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
Как нам это сделать?
Задача нетривиальная, такого мы еще не делали :/
Есть какие-то идеи? Попробуй предположить.
Вот что, например, мы можем сделать:
- Пройтись по всем элементам массива. Сравнивать каждый элемент со следующим (
[0]с[1],[1]с[2],[2]с[3]и т.д.). Если текущий элемент массива больше следующего, меняем их местами и переходим к следующему элементу. Если нет, оставляем как есть и идем дальше. - Таким образом, после первого прохождения по элементам массива самое большое значение (167) гарантированно будет в последней ячейке.
- Теперь снова пройдем по всем элементам массива начиная с элемента с индексом
[0], но до предпоследнего элемента (самое большое число уже на своем месте) и сделаем такие же сравнения и замены местами. В конце в предпоследней ячейке у нас окажется второе самое большое значение (99). - Повторим эту работу столько раз, сколько у нас в массиве элементов минус один.
Идею мы придумали, осталось только написать код. Выглядеть он будет так:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
for (int i = numbers.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
/*Сравниваем элементы попарно,
если они имеют неправильный порядок,
то меняем местами*/
if (numbers[j] > numbers[j + 1]) {
int tmp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = tmp;
}
}
}
}
}
Эээ… Выглядит несколько сложновато -_-
Даже если общий принцип работы понятен, приходится писать довольно много кода, чтобы решить такую несложную с виду задачу.
Окей, может мы просто переоценили себя? Наверное, задача, которую мы взяли, пока слишком сложна для нас. Давай попробуем сделать что попроще.
Например, возьмем тот же массив чисел.
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Наша задача это скопировать его содержимое в другой массив.
int [] numbersCopy = new int[10];
Подумай, как бы ты это сделал, используя те знания о массивах, которые у тебя уже есть?
Можно, например, пройтись в цикле по массиву numbers и по очереди записывать его элементы в numbersCopy:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = new int[10];
for (int i = 0; i < numbers.length; i++) {
numbersCopy[i] = numbers[i];
}
}
}
Ну-у-у, тут мы более-менее справились! Задача вроде как решена, хоть опять же: если ее нужно будет выполнять часто, в коде будет куча одинаковых циклов.
На самом деле, эти и другие задачи уже давно решены создателями Java, и нам не нужно "изобретать велосипед" и писать какой-то код собственного решения.
Класс Java Arrays
Решать типовые задачи при работе с массивами тебе поможет специальный класс Java,Arrays.
В этот класс были добавлены методы для решения самых распространенных задач, с которыми сталкиваются Java-программисты в работе.
Например, задача по сортировке массива, для которой мы сами пытались придумать решения, решается в одну строку:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
Метод Arrays.sort() выполняет сортировку массива. Причем заложенный в него алгоритм делает это намного эффективнее того кода, который написали мы.
Вывод на консоль:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
Обрати внимание: для преобразования массива в строку мы использовали еще один метод класса Arrays, Arrays.toString().
Сами по себе массивы в Java не переопределяют метод toString(). Поэтому если ты напишешь просто
System.out.println(numbers.toString());
будет вызван метод toString() класса Object. В случае с массивами вывод будет примерно такой:
[I@4554617c
Не будем сейчас подробно разбираться, почему вывод именно такой, главное это явно не то, что нам нужно. А вот Arrays.toString() сделал то, что мы и хотели.
Кстати, наша задача с копированием тоже легко решается в классе Arrays:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println(Arrays.toString(numbersCopy));
}
}
В метод Arrays.copyOf() мы передаем наш оригинальный массив (из которого надо скопировать значения) и длину нового массива, в который мы копируем данные. В данном случае в качестве длины мы указали numbers.length, т.к. хотим скопировать массив целиком. Если же мы хотим скопировать только несколько первых элементов, можно указать длину для нового массива меньше:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, 4);
System.out.println(Arrays.toString(numbersCopy));
}
}
Здесь мы указали длину нового массива, равного 4. Соответственно, только 4 первых элемента numbers будут скопированы в новый массив.
Вывод в консоль:
[167, -2, 16, 99]
Кстати, если нужно скопировать часть массива, но не с начала, а "из середины", Arrays позволяет сделать и это:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
System.out.println(Arrays.toString(numbersCopy));
}
}
Вывод:
[16, 99, 26, 92]
В новый массив были скопированы числа из ячеек со второй (включительно) по шестую (не включительно).
Кроме того, нам может понадобиться сравнить два массива между собой. Так же, как с методом toString(), сами по себе массивы не переопределяют метод equals(). Поэтому если мы попробуем сравнить их так:
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(numbers.equals(numbers2));
}
}
получим результат false. Ведь будет вызван метод Object.equals(), который сравнивает ссылки. А они, естественно, разные! Подробнее про сравнение объектов по содержимому и по ссылке мы разбирали в статье про методы equals и hashCode.
Но нам-то надо сравнить содержимое массивов, а не ссылки.
Класс Arrays содержит переопределенный метод equals(), который делает ровно то, что нам нужно:
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(Arrays.equals(numbers, numbers2));
}
}
Вывод:
true
Кстати, класс Arrays успешно работает не только с обычными массивами, но и с двумерными:
public class Main {
public static void main(String[] args) {
int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println("Равны ли эти двумерные массивы между собой?");
System.out.println(Arrays.deepEquals(numbers, numbersCopy));
System.out.println(Arrays.deepToString(numbersCopy));
}
}
Вывод:
Равны ли эти двумерные массивы между собой?
true
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Как видишь, метод Arrays.copyOf() справился с копированием и двумерного массива. Обрати внимание, что в таком случае при копировании двумерного массива происходит так называемое "поверхностное копирование".
А для сравнения двумерных массивов и их вывода на консоль предусмотрены специальные методы, deepEquals и deepToString();
Основные методы класса Arrays
Соберем разобранные методы в одну таблицу:| Метод | Что делает |
|---|---|
Arrays.sort(array) | сортирует массив по возрастанию |
Arrays.toString(array) | преобразует массив в читаемую строку |
Arrays.copyOf(array, length) | копирует массив (можно задать другую длину) |
Arrays.copyOfRange(array, from, to) | копирует часть массива (from включительно, to не включительно) |
Arrays.equals(a, b) | сравнивает два массива по содержимому |
Arrays.deepEquals(a, b) | сравнивает многомерные массивы по содержимому |
Arrays.deepToString(array) | выводит многомерный массив в читаемом виде |
Arrays на сайте Oracle.
Удачи в обучении!
Читайте также
- Массивы в Java: что такое массив, как его создать и обращаться к элементам.
- Класс ArrayList: динамический список, который в отличие от массива расширяется автоматически.
- Методы equals и hashCode: почему == сравнивает ссылки, а не содержимое.
Вопросы и ответы
Что такое класс Arrays в Java?
Это служебный классjava.util.Arrays с готовыми статическими методами для типовых операций с массивами: сортировки, копирования, сравнения и преобразования в строку.
Как отсортировать массив в Java?
Одной строкой:Arrays.sort(numbers). Метод сортирует по возрастанию и работает эффективнее, чем самописный цикл.
Как вывести массив на экран?
ЧерезArrays.toString(array). Обычный System.out.println(array) выведет служебную строку с хеш-кодом, потому что массивы не переопределяют toString().
Как скопировать массив?
Arrays.copyOf(array, length) копирует массив целиком или первые length элементов, а Arrays.copyOfRange(array, from, to) копирует часть по диапазону.
Как сравнить два массива по содержимому?
ЧерезArrays.equals(a, b). Оператор == и array.equals() сравнивают ссылки, а не содержимое, поэтому для одинаковых по данным массивов вернут false.
Как работать с двумерными массивами?
Для сравнения и вывода многомерных массивов используютArrays.deepEquals() и Arrays.deepToString(), которые заходят вглубь вложенных массивов.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ