Риша, мне прямо не терпится узнать об остальных методах класса Arrays.

— Такое рвение к учёбе не может не радовать старого учителя!..Впрочем, если ты так уж хотел всё разузнать, добрый волшебник Google тебе в помощь и днём, и ночью.

Ээээ…

— Шучу. Отчасти. Конечно я расскажу лучше, но если что — помни о добром волшебнике. И сегодняшнюю лекцию я начну с метода, который называется Arrays.fill

— Очень часто у Java-программистов при работе с массивами возникает задача: заполнить массив одинаковыми значениями. Можно, конечно, написать цикл и просто в цикле присвоить каждой ячейке массива определенное значение:

int[] x = new int[100];
for (int i = 0; i < x.length; i++)
x[i] = 999;

— Вместо всего этого можно вызвать метод Arrays.fill(), который делает ровно то же самое: заполняет переданный массив переданным значением. Вот как это выглядит:

Arrays.fill(имя, значение)

И код из примера выше можно сделать немного компактнее и понятнее:

int[] x = new int[100];
Arrays.fill(x, 999);

Красиво!

— А еще с помощью метода Arrays.fill() можно заполнить определенным значением не весь массив, а его часть:

Arrays.fill(имя, первый, последний, значение)

— Где первый и последний — это номера первой и последней ячеек, которые нужно заполнить.

По старой доброй (или не очень доброй) традиции Java, последний элемент не входит в диапазон.

Пример:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Arrays.fill(x, 3, 7, 999);


String str = Arrays.toString(x);

Заполняем ячейки x[3], x[4], x[5], x[6] значениями 999. Нумерация ячеек массива с нуля!

Переменная str содержит значение
"[1, 2, 3, 999, 999, 999, 999, 8, 9, 10]"

— Метод Arrays.fill() работает только с одномерными массивами. Если в него передать двумерный массив, он будет обработан как одномерный, со всеми вытекающими последствиями.

undefined
6
Задача
Java Syntax Pro, 6 уровень, 8 лекция
Недоступна
Заполняем массив
Реализуй статический метод main(String[]), который заполняет массив array значениями valueStart и valueEnd. Если длина массива четная, его первую половину нужно заполнить значениями valueStart, а вторую — valueEnd. Если длина массива нечётная, то первую большую часть заполнить значениями valueStart

Arrays.copyOf()

— Амиго, ответь, пожалуйста, как поменять размер контейнера массива после его создания?

Эммм… Вопрос с подвохом, насколько я понял? Но я уже не настолько зелёный. Правильный ответ: никак! Нельзя поменять размер контейнера массива после его создания.

— А если очень хочется?

Всё равно нельзя!

— На самом деле, если очень хочется, то можно! С помощью программистского финта:

  1. Сначал создаёшь новый массив нужной длины
  2. Затем копируешь в него все элементы из первого массива.

— Именно эти два действия делает метод Arrays.copyOf(). Вот как выглядит его вызов:

тип[] имя2 = Arrays.copyOf(имя, длина);

— Этот метод не меняет существующий массив, вместо этого он создает новый массив и копирует в него элементы старого массива.

А что если длина нового массива меньше длины существующего?

— Отличный вопрос, Амиго! Если элементы не поместились, то лишние значения просто игнорируются.

А если наоборот, остались лишние ячейки, что в них изначально находится?

— Если длина нового массива больше длины старого, ячейки заполняются нулями.

Пример:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int[] x2 = Arrays.copyOf(x, 5);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOf(x, 15);
String str3 = Arrays.toString(x3);


Переменная str2 содержит значение
"[1, 2, 3, 4, 5]"

Переменная str3 содержит значение
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0]"

Arrays.copyOfRange()

— А что делать, если тебе нужно получить массив длиной 5 из массива длины 10, но чтобы в нем оказались не первые 5 элементов, а 5 последних? Для этого случая тебе понадобится еще один метод класса Arrays. Называется он Arrays.copyOfRange(). Вот как выглядит его вызов:

тип[] имя2 = Arrays.copyOfRange(имя, первый, последний);

— Этот метод тоже создает новый массив, но заполняет его данными из произвольного места исходного массива. Где первый и последний — это номера первой и последней ячеек, которые должны быть в новом массиве. Можешь сказать, входит ли в этот диапазон последний элемент?

Ха! Как говаривал мой великий учитель, «по старой доброй традиции Java, последний элемент не входит в диапазон».

— Амиго, ты растёшь буквально на глазах.

Пример:

int[] x = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

int[] x2 = Arrays.copyOfRange(x, 5, 10);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOfRange(x, 5, 15);
String str3 = Arrays.toString(x3);


Переменная str2 содержит значение
"[16, 17, 18, 19, 20]"

Переменная str3 содержит значение
"[16, 17, 18, 19, 20, 0, 0, 0, 0, 0]"
undefined
6
Задача
Java Syntax Pro, 6 уровень, 8 лекция
Недоступна
Делим массив
Реализуй метод main(String[]), который делит массив array на два подмассива и заполняет ими двумерный массив result. Если длина массива нечетная, то большую часть нужно скопировать в первый подмассив. Для разделения массива используй метод Arrays.copyOfRange(int[], int, int). Порядок элементов не м

Arrays.sort()

— Ну и напоследок я оставил самое...ммм… приятное — сортировку. В программировании сортировать массивы приходится очень часто. Вот тебе топ-3 самых популярных действий при работе с массивами:

  • Сортировка массива
  • Поиск минимального (или максимального) элемента массива
  • Определение индекса элемента в массиве (поиск элемента в массиве)

— Эффективные алгоритмы сортировки, надо сказать, не так уж просто написать. Точнее, это нормальная задачка, и тебе, как ученику, иногда не помешает поупражняться в написании алгоритмов сортировок. Но в работе лучше не тратить время на изобретение велосипеда. Разработчики Java включили в класс Arrays метод sort(). Вот как выглядит его вызов:

Arrays.sort(имя);

Этот метод сортирует переданный массив по возрастанию.

Пример:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x);
String str = Arrays.toString(x);


Переменная str содержит значение
"[-20, -20, -20, -2, 0, 3, 8, 11, 99, 999]"

Отлично! Вызвал один метод, и отсортированный массив готов. Красота!

— Кстати, сортировать можно не только весь массив, но и часть массива. Вот как выглядит его вызов:

Arrays.sort(имя, первый, последний);

— Где первый и последний — это номера первой и последней ячеек, которых должна коснуться сортировка. И…

Я уже знаю, что ты скажешь! «По старой доброй традиции Java, последний элемент не входит в диапазон».

Пример:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x, 4, 8);
String str = Arrays.toString(x);


Переменная str содержит значение
"[11, -2, 3, 0, -20, -20, 8, 999, 99, -20]"

— В Java для сортировки массивов используется самый быстрый алгоритм сортировки — QuickSort. Скорость его сортировки зависит от размера массива и рассчитывается по формуле N*Log(N).

— Сортировка массива из 1000 элементов будет содержать около 10,000 сравнений ячеек массива. Сортировка массива из миллиона элементов будет содержать около 20 миллионов сравнений.

Не так уж и много сравнений, если учесть количество элементов!

— Вот и я об этом же. Алгоритм QuickSort — очень эффективный.

undefined
6
Задача
Java Syntax Pro, 6 уровень, 8 лекция
Недоступна
Сортировка массива
Реализуй метод main(String[]), который сортирует массив array по возрастанию. Для сортировки массива используй метод Arrays.sort(int[]).

Arrays.binarySearch()

— Ну и последний из самых интересных методов класса Arrays умеет искать заданное значение в массиве. Это не обычный поиск, а так называемый бинарный поиск. Суть его заключается вот в чем:

  • Предварительно массив сортируется.
  • Затем средний элемент массива сравнивается с искомым (с тем, который мы ищем).
  • Если искомый больше среднего, поиск продолжается в правой половине массива.
  • Если искомый элемент меньше среднего, поиск продолжается в левой половине массива.

— Благодаря тому, что массив отсортирован, можно за одно сравнение отбросить половину массива. Затем на следующем шаге отбросить еще половину и так далее.

— Класс! Идём к цели прям очень быстро!

— Точно. В массиве из миллиона(!) элементов алгоритм бинарного поиска может найти индекс нужного элемента всего за 20 сравнений. Минусом алгоритма является то, что массив предварительно нужно отсортировать, а сортировка тоже занимает время.

Вот как выглядит его вызов:

int index = Arrays.binarySearch(имя, значение);

— Где имя — это имя массива, который нужно передать уже отсортированным (например, с помощью функции Arrays.sort()). значение — это тот элемент, который ищется в массиве. Метод возвращает результат — индекс искомого элемента в массиве (номер ячейки массива).

Примеры:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};
Arrays.sort(x);

int index1 = Arrays.binarySearch(x, 0);
int index2 = Arrays.binarySearch(x, -20);
int index3 = Arrays.binarySearch(x, 99);
int index4 = Arrays.binarySearch(x, 5);
x содержит
{-20, -20, -20, -2, 0, 3, 8, 11, 99, 999}

4
1 (также подходили индексы 0 и 2)
8
-7

А что, если искомых элементов в массиве несколько?

— Правильный вопрос, Амиго. В таком случае алгоритм вернет номер одного из них (нет гарантий, что это будет, допустим, самый первый или наоборот — самый последний из одинаковых элементов).

А если в массиве вообще нет того, что мы ищем?

— В таком случае алгоритм вернёт отрицательный индекс.

undefined
6
Задача
Java Syntax Pro, 6 уровень, 8 лекция
Недоступна
Есть ли кто?
Реализуй метод main(String[]), который выводит в консоль true, если элемент содержится в переданном массиве, иначе — false. Массив array не должен изменять расположение своих элементов. Для поиска элемента в массиве нужен бинарный поиск. Чтобы это сделать, используй статический метод Arrays.binaryS

Документация

Всё понятно, Риша! Было очень интересно.

— Если тебе прям вот очень интересно, то полистай на досуге официальную документацию по классу Arrays и его методах в на сайте Oracle:

https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Arrays.html

— Можешь присмотреться, например, к методам Arrays.mismatch() и Arrays.compare(). Скорее всего, ты найдешь им полезное применение.

— И пусть тебя не смущает количество методов — там у каждого метода есть 5-10 копий, которые отличаются только типом параметров.