Методы копирования массивов java

Методы копирования массивов java

Статья хорошая, бесспорно. Но иногда статья дублирует материал лекций, не привнося ничего нового.. Эта одна из таких. Поменьше бы таких «статей для рейтинга» и побольше бы действительно нужного материала. Или дополняющего или расширяющего.

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

«А для сравнения двумерных массивов и их вывода на консоль предусмотрены специальные методы — deepEquals и deepToString().» Если вдруг не поймете, то здесь deepToString() — превращает двумерный массив в строку, но никак не выводит на консоль, за вывод на консоль отвечает System.out.println(. )

«Обрати внимание, что в таком случае при копировании двумерного массива происходит так называемое «поверхностное копирование».» Почему автор не посчитал нужным раскрыть смысл фразы «поверхностное копирование»?

JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Источник

Методы копирования массивов java

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

Читайте также:  Ошибка при установке питона 0x80070643

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

Следует иметь ввиду небольшой нюанс работы метода, связанный с тем, что если количество копируемых элементов указано больше, чем их содержит массив, то 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)); > > 

Источник

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