Глубокая копия массива объектов

Я хочу сделать глубокую копию массива объектов, используя конструктор.

public class PositionList { private Position[] data = new Position[0]; public PositionList(PositionList other, boolean deepCopy) { if (deepCopy){ size=other.getSize(); data=new Position[other.data.length]; for (int i=0;i<data.length;i++){ data[i]=other.data[i]; } 

Однако то, что у меня выше по какой-то причине, не работает. У меня есть автоматические тесты, которые я запускаю, и его провал этих тестов. Таким образом, theres ошибка здесь, что я не уверен, что это такое.

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

 data[i] = other.data[i]; 

к некоторой вещи, которая назначает копию other.data[i] data[i] . Как вы это делаете, это зависит от classа Position . Возможными альтернативами являются:

  • конструктор копирования:

    data[i] = new Position(other.data[i]);

  • заводской метод:

    data[i] = createPosition(other.data[i]);

  • клон:

    data[i] = (Position) other.data[i].clone();

Заметки:

  1. Вышеизложенное предполагает, что конструктор копирования, фабричный метод и метод клона соответственно реализуют «правильный» вид копирования в зависимости от classа Position; Смотри ниже.
  2. Подход clone будет работать, только если Position явно поддерживает его, и это обычно рассматривается как низшее решение. Кроме того, вам нужно знать, что встроенная реализация clone (то есть метод Object.clone() ) делает мелкую копию.

На самом деле общая проблема реализации глубокого копирования в Java сложна. В случае classа Position можно предположить, что атрибуты являются всеми примитивными типами (например, ints или double), и поэтому глубокое или мелкое копирование является спорным. Но если есть ссылочные атрибуты, тогда вам нужно полагаться на метод конструктора / фабричного метода копирования / клонирования, чтобы выполнить требуемый тип копирования. В каждом случае его необходимо запрограммировать. И в общем случае (где вам приходится иметь дело с циклами) это сложно и требует, чтобы каждый class применял специальные методы.

Существует еще один возможный способ копирования массива объектов. Если объекты в массиве сериализуемы , их можно скопировать с помощью ObjectOutputStream и ObjectInputStream а затем десериализовать массив. Однако:

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

Копирование по сериализации не рекомендуется. Было бы лучше поддержать клонирование или какой-либо другой метод.

В целом, на Java лучше избегать глубокого копирования.

Наконец, чтобы ответить на ваш вопрос о конструкторах экземпляров classов classов, я ожидаю, что это примерно так:

 public class Position { private int x; private int y; ... public Position(Position other) { this.x = other.x; this.y = other.y; } ... } 

Как говорит @Turtle, нет никакой магии. Вы реализуете конструктор (вручную), который инициализирует его состояние, копируя из существующего экземпляра.

Когда ты говоришь:

 data[i]=other.data[i]; 

Вы просто копируете список ссылок (предполагая, что это массив объектов). Если вы хотите сделать глубокую копию, вам нужно использовать new для создания нового экземпляра каждого объекта в массиве.

Вместо того, чтобы говорить:

 data[i]=other.data[i] 

Вы захотите создать конструктор копирования для Position (другими словами, конструктор для позиции, который принимает другую Position и копирует примитивные данные внутри него) и говорят data[i]=new Position(other.data[i]);

В основном ваш конструктор «глубокой копии» PositionList является конструктором копирования, хотя конструктор копирования имеет тенденцию указывать глубокую копию, поэтому параметр deepCopy не нужен.

Вот функция, которую я использую:

 function copy(arr) { return arr .map(x => Object .keys(x) .reduce((acc, y) => { acc[y] = x[y] return acc }, {})) } 

Он работает только с массивами с объектами с одним уровнем.

Это должно сделать «глубокую» копию

 int [] numbers = { 2, 3, 4, 5}; int [] numbersClone = (int[])numbers.clone(); 
  • Redim сохранить в C #?
  • ArrayIndexOutOfBoundsException при повторении всех элементов массива
  • Как скопировать файл .txt в массив символов в c ++
  • Асинхронный доступ к массиву в Firebase
  • Инициализация массива PowerShell
  • Различие между емкостью списка массивов и размером массива
  • Почему массив реализует IList?
  • Как объявить двухмерный массив типа string в Objective-C?
  • Как инициализировать std :: array элегантно, если T не является конструктивным по умолчанию?
  • Каков самый элегантный способ проверить, истинны ли все значения в булевом массиве?
  • Индекс массива не связан с C
  • Interesting Posts

    проблема с оберткой заголовков столбцов jqGrid в IE

    Как я могу переопределить DNS-серверы Windows10 по умолчанию для использования DNS-серверов, назначенных OpenVPN

    Ссылка – проверка пароля

    Структурный конструктор в C ++?

    java.lang.IllegalMonitorStateException: объект не заблокирован streamом перед wait ()?

    Mount cifs для 2 пользователей

    Как использовать алгоритм SIFT для вычисления того, как похожи два изображения?

    как проверить Wi-Fi или 3g-сеть доступна на Android-устройстве

    Держите iphone активным во время запуска программы

    В чем разница между «длинным», «длинным длинным», «длинным int» и «long long int» в C ++?

    Каков наилучший тип данных для использования в Java-приложении?

    Как связать использование GCC без -l или пути hardcoding для библиотеки, которая не соответствует соглашению об именах libNAME.so?

    Вычисление суммы повторяющихся элементов в AngularJS ng-repeat

    Дождитесь загрузки видео в формате HTML5

    Как переупорядочить папки? (Как показано в `ls -U`)

    Давайте будем гением компьютера.