W3docs

Утилитный класс Java Arrays

Используйте класс java.util.Arrays для сортировки, поиска, заполнения, сравнения и преобразования массивов в Java.

java.util.Arrays — это набор вспомогательных методов для работы с массивами из стандартной библиотеки. Это final-класс, содержащий только static-методы — вы никогда не создаёте его экземпляр, а просто вызываете методы напрямую: Arrays.sort(...), Arrays.toString(...) и так далее. Зная, что в нём есть, вы сможете писать гораздо более компактный код для работы с массивами.

Эта глава — экскурсия по классу. Сортировка и копирование рассматриваются в отдельных главах; здесь мы сосредоточимся на остальном.

Импорт

import java.util.Arrays;

Почти все примеры ниже предполагают наличие этого импорта.

toString и deepToString

Превращают массив в читаемую строку. toString работает с одномерными массивами:

int[] data = {3, 1, 4};
String s = Arrays.toString(data);   // "[3, 1, 4]"

deepToString рекурсивно форматирует вложенные массивы:

int[][] grid = {{1, 2}, {3, 4}};
String s = Arrays.deepToString(grid);   // "[[1, 2], [3, 4]]"

Оба метода работают как с примитивными типами элементов, так и с объектами.

equals и deepEquals

== сравнивает ссылки на массивы. Чтобы сравнить содержимое:

int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
boolean same = Arrays.equals(a, b);   // true

Для вложенных массивов используйте deepEquals:

int[][] g1 = {{1, 2}, {3, 4}};
int[][] g2 = {{1, 2}, {3, 4}};
boolean same = Arrays.deepEquals(g1, g2);   // true

Оба метода считают null == null равным true.

hashCode и deepHashCode

Хеши, основанные на содержимом, полезны, когда класс оборачивает массив и требует реализации equals/hashCode:

int[] data = {1, 2, 3};
int h = Arrays.hashCode(data);

Если вы переопределяете equals с использованием Arrays.equals, то должны переопределить hashCode с использованием Arrays.hashCode, чтобы соблюсти контракт.

fill

Установить все элементы в заданное значение или заполнить диапазон:

int[] data = new int[5];
Arrays.fill(data, 7);              // {7, 7, 7, 7, 7}
Arrays.fill(data, 1, 4, 0);        // zero indexes 1..3

sort и parallelSort

Сортировка на месте по возрастанию:

int[] data = {3, 1, 4, 1, 5};
Arrays.sort(data);                 // {1, 1, 3, 4, 5}

Для очень больших массивов можно использовать parallelSort, чтобы распределить работу по нескольким ядрам. Подробнее о сортировке — примитивы, объекты, произвольный порядок — рассказано в главе Сортировка массивов.

binarySearch

Найти элемент в отсортированном массиве за O(log n):

int[] sorted = {1, 3, 5, 7, 9};
int idx = Arrays.binarySearch(sorted, 5);   // 2
int miss = Arrays.binarySearch(sorted, 6);  // negative — encodes insertion point

Если элемент не найден, возвращаемое значение равно -(insertionPoint) - 1. Таким образом, miss == -4 означает, что 6 должно стоять на индексе 3. Если входной массив не отсортирован, результат не определён — сначала отсортируйте.

copyOf и copyOfRange

Возвращают новый массив, копируя значения из существующего:

int[] data = {1, 2, 3, 4, 5};
int[] all   = Arrays.copyOf(data, data.length);    // exact copy
int[] grown = Arrays.copyOf(data, 8);              // padded with zeros
int[] slice = Arrays.copyOfRange(data, 1, 4);      // {2, 3, 4}

Подробнее об этом рассказано в главе Копирование массивов.

asList

Обернуть массив ссылочных типов в List фиксированного размера:

String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);

Список опирается на массив — list.set(0, "z") изменяет и arr[0]. Размер фиксирован, поэтому add/remove выбрасывают исключение. С примитивными массивами поведение отличается от ожидаемого: Arrays.asList(new int[]{1, 2, 3}) создаёт List<int[]> длиной один элемент. Для примитивов сначала выполните боксинг через стримы.

stream

Получить стрим из числового или объектного массива:

int[] nums = {3, 1, 4, 1, 5};
int sum = Arrays.stream(nums).sum();
double avg = Arrays.stream(nums).average().orElse(0);

Для массивов объектов Arrays.stream(arr) возвращает Stream<T>. Также есть формы с ограничением диапазона — Arrays.stream(arr, from, to).

setAll и parallelSetAll

Заполнить массив с помощью функции от индекса:

int[] squares = new int[6];
Arrays.setAll(squares, i -> i * i);
// {0, 1, 4, 9, 16, 25}

Используйте setAll, когда хотите получить производную последовательность, а цикл for был бы лишним.

compare и mismatch (Java 9+)

Arrays.compare(a, b) возвращает отрицательное, нулевое или положительное число — лексикографический порядок по элементам:

int[] a = {1, 2, 3};
int[] b = {1, 2, 4};
int cmp = Arrays.compare(a, b);   // negative — a is smaller

Arrays.mismatch(a, b) возвращает индекс первого отличающегося элемента или -1, если массивы равны:

int diff = Arrays.mismatch(a, b);   // 2

Если один массив является собственным префиксом другого, более короткий считается «меньшим» по compare, а mismatch возвращает длину более короткого массива:

int[] s = {1, 2};
int[] l = {1, 2, 3};
Arrays.compare(s, l);    // negative — s is a prefix, so it sorts first
Arrays.mismatch(s, l);   // 2 — they agree up to index 2, then s runs out

Эти методы удобны, когда нужен порядок или информация о месте расхождения без написания цикла вручную.

Распространённые ловушки

Несколько подводных камней встречаются достаточно часто, чтобы перечислить их в одном месте:

  • == — не сравнение содержимого. a == b равно true только тогда, когда оба имени указывают на один и тот же объект-массив. Используйте Arrays.equals (или Arrays.deepEquals для вложенных массивов) для сравнения содержимого.
  • toString поверхностный. Arrays.toString(grid) на int[][] выведет что-то вроде [[I@1b6d3586, ...] — внутренние массивы используют свой стандартный Object.toString. Используйте Arrays.deepToString, когда массив содержит другие массивы.
  • asList с примитивным массивом удивляет. Arrays.asList(new int[]{1, 2, 3}) — это одноэлементный List<int[]>, а не List<Integer> длиной три, потому что int[] является единым объектом. Используйте Arrays.stream(arr).boxed().toList() (Java 16+), чтобы получить нужный список.
  • asList имеет фиксированный размер. Это представление исходного массива, поэтому set работает, но add и remove выбрасывают UnsupportedOperationException. Оберните в new ArrayList<>(Arrays.asList(...)), если нужна возможность добавления элементов.
  • binarySearch требует отсортированного массива. На неотсортированных данных результат не определён — исключение не будет выброшено, просто вернётся неверный индекс. Сначала отсортируйте.

Практический пример

Приведённый ниже пример объединяет большинство методов. Запустите его и сравните вывод с комментариями выше — binarySearch возвращает 5 для значения 5, отрицательный результат для отсутствующего элемента и список [red, green, blue] из asList:

java— editable, runs on the server

Что дальше

Мы рассмотрели Arrays.sort лишь вскользь. Следующая глава, Сортировка массивов, подробно разбирает, как работает сортировка для примитивов и объектов, по возрастанию и убыванию, а также как задавать собственный порядок с помощью Comparator.

Практика

Практика
Почему Arrays.binarySearch быстрее линейного перебора?
Почему Arrays.binarySearch быстрее линейного перебора?
Was this page helpful?