Метод system arraycopy java

Метод system arraycopy java

Метод Arrays.copyOf() принимает 2 параметра: копируемый массив и количество копируемых значений, которое определяет также длину нового массива. Т. к. мы хотим скопировать массив целиком, то указываем в качестве количества длину исходного массива.

Если вам требуется скопировать не весь массив, а только какую-то его часть, то вместо длины следует указать необходимое значение: это может быть как целочисленный литерал, так и значение переменной.

Следует иметь ввиду небольшой нюанс работы метода, связанный с тем, что если количество копируемых элементов указано больше, чем их содержит массив, то copyOf() дополнит итоговый массив значениями по умолчанию.

Пусть имеется заполненный массив чисел, в который необходимо добавить еще одно число. Т. к. размер уже созданного массива менять нельзя, то создадим новый с увеличенным размером:

 int[] srcArr = ; int[] destArr = Arrays.copyOf(srcArr, srcArr.length + 3); System.out.println(Arrays.toString(destArr)); destArr[srcArr.length] = 6; destArr[srcArr.length + 1] = 7; System.out.println(Arrays.toString(destArr)); 
 [1, 2, 3, 4, 5, 0, 0, 0] [1, 2, 3, 4, 5, 6, 7, 0] 
 String[] letters = ; int len = letters.length; int newLen = len + (int) (len * 0.75); System.out.println("Длина нового массива = " + newLen); String[] destArr = Arrays.copyOf(letters, newLen); System.out.println(Arrays.toString(destArr)); destArr[len] = "D"; System.out.println(Arrays.toString(destArr)); 
 Длина нового массива = 5 [A, B, C, null, null] [A, B, C, D, null] 

В данном коде создаются два массива типа String. Длина второго массива (newLen) вычисляется по формуле, которая позволяет увеличивать его размер на 75%. Также видно, что copyOf заполняет пустые ячейки null’ом.

Если требуется скопировать значения не с начала массива (или не до конца), то необходимо использовать Arrays.copyOfRange() (появился в Java 1.6). Данный метод позволяет копировать определенный диапазон значений массива, начиная с указанного индекса:

 int[] srcArr = ; int[] destArr = Arrays.copyOfRange(srcArr, 1, 3); System.out.println(Arrays.toString(destArr)); 

Метод copyOfRange() принимает 3 параметра: исходный (копируемый) массив; индекс в исходном массиве, с которого будет начинаться копирование; третий параметр — конечный индекс до которого будут копироваться элементы (значение под этим индексом не включается в копирование).

Читайте также:  Эффекты перехода страниц

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

 import java.util.Arrays; public class Main < public static void main(String[] args) < double[] srcArr = ; double max = srcArr[0]; int maxNumIndex = 0; for (int i = 1; i < srcArr.length; i++) < if (srcArr[i] >max) < maxNumIndex = i; max = srcArr[i]; >> double[] destArr = Arrays.copyOfRange(srcArr, maxNumIndex, srcArr.length); System.out.println(Arrays.toString(destArr)); > > 

Метод copyOfRange(), так же как и copyOf(), если количество копируемых элементов указано больше, чем их содержит массив, дополняет итоговый массив значениями по умолчанию.

В Java есть еще один способ скопировать массив — с помощью нативного (native) метода arraycopy(), расположенного в классе System.

Его работа имеет принципиальное отличие от копирования элементов массива в цикле: он копирует не поэлементно, а целыми блоками памяти, что влияет положительно на производительность.

Данный класс находится в пакете java.lang, и его не нужно импортировать — это делается автоматически.

Нативными называются методы, реализация которых написана на каком-то другом языке, отличном от Java (например, С/C++), под конкретную ОС, что делает их код платформозависимым, т. е. «родным» для конкретной системы.

Получается, что сигнатуру метода arraycopy() с ключевым словом native мы можем наблюдать в классе System, а вот реализация, написанная на языках C/C++, находится совсем в другом месте. Она является частью скомпилированной в виде машинного (бинарного) кода библиотеки внутри JVM.

 @IntrinsicCandidate public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 

Запомнить последовательность аргументов, которые принимает метод, не сложно. Рассуждать можно следующим образом: из исходного массива (src), начиная с начальной позиции (srcPos), нужно скопировать данные в другой массив (dest), в такую-то позицию (destPos), в таком-то количестве (length).

Обратите внимание, что оба массива имеют тип Object. Это сделано для универсальности, чтобы данный метод мог работать с массивами любого типа.

Над сигнатурой метода мы также можем наблюдать аннотацию @IntrinsicCandidate (до Java 16 она называлась @HotSpotIntrinsicCandidate), сообщающую о том, что JVM вместо вызова кода, написанного на другом языке (а такие вызовы могут негативно влиять на производительность и делают невозможным выполнять оптимизации кода), может использовать внутреннюю (встроенную) реализацию данного метода, которая есть у JIT (Just-in-Time — технология увеличения производительности программ за счет компиляции часто используемых частей кода).

В режиме интерпретатора (когда JVM выполняет вашу программу байт-код за байт-кодом) виртуальной машиной будет запускаться native-версия arraycopy(), но проработав какое-то время и собрав статистику, при определенных условиях она будет рассматривать методы с подобными аннотациями как кандидаты на замену native-кода внутренним машинным кодом.

Разберем пример работы с arraycopy(). Пусть требуется удалить значение по индексу 0, а затем сдвинуть влево все числа, стоящие от него справа:

 import java.util.Arrays; class Main < public static void main(String[] args) < int[] arr = ; System.arraycopy(arr, 1, arr, 0, arr.length - 1); System.out.println(Arrays.toString(arr)); arr[arr.length - 1] = 0; System.out.println(Arrays.toString(arr)); > > 

Источник

Оцените статью