← Назад к вопросам

Какой знаешь эффективный способ копирования массива?

2.2 Middle🔥 201 комментариев
#Коллекции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Эффективные способы копирования массива в Java

Обзор методов

В Java существует несколько способов копирования массивов с разной производительностью и применением.

1. System.arraycopy() - Самый быстрый способ

System.arraycopy() — это встроенный метод JVM, который работает на уровне операционной системы и является самым быстрым.

int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[original.length];

// System.arraycopy(источник, начало, назначение, начало, длина)
System.arraycopy(original, 0, copy, 0, original.length);

System.out.println(Arrays.toString(copy)); // [1, 2, 3, 4, 5]

Преимущества:

  • Самый быстрый способ (реализован на нативном коде)
  • Работает с примитивами и объектами
  • Позволяет копировать часть массива

Синтаксис:

System.arraycopy(
    Object src,     // Исходный массив
    int srcPos,     // Начальная позиция в источнике
    Object dest,    // Целевой массив
    int destPos,    // Начальная позиция в цели
    int length      // Количество элементов для копирования
);

2. Arrays.copyOf() - Удобный встроенный способ

Arrays.copyOf() — статический метод Java, возвращающий новый массив.

int[] original = {1, 2, 3, 4, 5};

// Копирование всего массива
int[] copy = Arrays.copyOf(original, original.length);

// Копирование первых 3 элементов
int[] partialCopy = Arrays.copyOf(original, 3); // [1, 2, 3]

// Копирование с расширением (новые элементы = 0 для int)
int[] extended = Arrays.copyOf(original, 10); // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

Преимущества:

  • Очень удобен в использовании
  • Может менять размер массива
  • Создаёт новый массив нужного размера
  • Работает с generics

3. Arrays.copyOfRange() - Копирование диапазона

Для копирования части массива с начального до конечного индекса.

int[] original = {1, 2, 3, 4, 5};

// Копирование элементов с индекса 1 до 4 (исключая 4)
int[] copy = Arrays.copyOfRange(original, 1, 4); // [2, 3, 4]

4. Цикл (самый медленный, но контролируемый)

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

int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[original.length];

for (int i = 0; i < original.length; i++) {
    copy[i] = original[i];
}

5. Клонирование массива

Метод clone() создаёт поверхностную копию массива.

int[] original = {1, 2, 3, 4, 5};
int[] copy = original.clone();

System.out.println(Arrays.toString(copy)); // [1, 2, 3, 4, 5]

Сравнение производительности

public class ArrayCopyPerformance {
    public static void main(String[] args) {
        int[] original = new int[1000000];
        for (int i = 0; i < original.length; i++) {
            original[i] = i;
        }
        
        // System.arraycopy() - самый быстрый
        long start = System.nanoTime();
        int[] copy1 = new int[original.length];
        System.arraycopy(original, 0, copy1, 0, original.length);
        System.out.println("System.arraycopy: " + (System.nanoTime() - start) + " ns");
        
        // Arrays.copyOf() - немного медленнее
        start = System.nanoTime();
        int[] copy2 = Arrays.copyOf(original, original.length);
        System.out.println("Arrays.copyOf: " + (System.nanoTime() - start) + " ns");
        
        // clone() - похож на Arrays.copyOf
        start = System.nanoTime();
        int[] copy3 = original.clone();
        System.out.println("clone(): " + (System.nanoTime() - start) + " ns");
        
        // Цикл - медленный
        start = System.nanoTime();
        int[] copy4 = new int[original.length];
        for (int i = 0; i < original.length; i++) {
            copy4[i] = original[i];
        }
        System.out.println("for loop: " + (System.nanoTime() - start) + " ns");
    }
}

Копирование объектов в массиве (поверхностное vs глубокое)

Поверхностное копирование (все методы выше)

String[] original = {"Hello", "World"};
String[] copy = Arrays.copyOf(original, original.length);

// Строки одинаковые по содержимому
System.out.println(Arrays.equals(original, copy)); // true

// Но это ссылки на одни и те же объекты
System.out.println(original[0] == copy[0]); // true (одинаковые объекты)

Глубокое копирование (для изменяемых объектов)

class Person {
    String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    public Person clone() {
        return new Person(this.name);
    }
}

Person[] original = {new Person("Ivan"), new Person("Maria")};
Person[] deepCopy = new Person[original.length];

for (int i = 0; i < original.length; i++) {
    deepCopy[i] = original[i].clone();
}

// Теперь это совсем другие объекты
System.out.println(original[0] == deepCopy[0]); // false

Рекомендации

Используй System.arraycopy() когда:

  • Нужна максимальная производительность
  • Копируешь большие массивы
  • Знаешь точные размеры

Используй Arrays.copyOf() когда:

  • Нужна удобство и читаемость
  • Массив может менять размер
  • Это не критичная по производительности операция

Используй clone() когда:

  • Нужна простота и ясность кода
  • Копируешь весь массив целиком

Используй цикл когда:

  • Нужна трансформация при копировании
  • Требуется глубокое копирование
  • Нужен особый контроль процесса

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

public class ArrayUtils {
    
    // Для примитивов - используй System.arraycopy
    public static int[] copyLargeIntArray(int[] source) {
        int[] copy = new int[source.length];
        System.arraycopy(source, 0, copy, 0, source.length);
        return copy;
    }
    
    // Для объектов с глубоким копированием
    public static <T extends Cloneable> T[] deepCopy(T[] source) {
        T[] copy = source.clone();
        for (int i = 0; i < source.length; i++) {
            if (source[i] != null) {
                try {
                    copy[i] = (T) source[i].getClass().getMethod("clone").invoke(source[i]);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return copy;
    }
}

Резюме

System.arraycopy() — самый быстрый и рекомендуется для больших массивов. Arrays.copyOf() — лучший выбор для обычного использования благодаря удобству. Выбор метода зависит от задачи, размера массива и требований к производительности.