как возможна глубокая копия Java в этой ситуации

ПРИМЕЧАНИЕ. Я просмотрел разные места, включая stackoverflow, и не нашел решения этой проблемы.

ПРОБЛЕМА:

class Animal{

AnimalGroup animalGroup;

}

class AnimalGroup{

List<Animal> animalList;

}

class MainProgram{

// Map<groupRank, animalGroup>
Map<Integer, AnimalGroup> rankedAnimalGroups;

}

Примечание. Очевидно, что одно животное может принадлежать только одной группе животных.

Я хочу глубоко скопировать карту rankedAnimalGroups.

Случай 1: клонирование

Я сделаю свое животное и группу животных клонируемыми.

Метод клонирования в AnimalGroup

protected Object clone() throws CloneNotSupportedException {
    AnimalGroup clonedAnimalGroup = (AnimalGroup)super.clone();
    for(Animal animal: animalList)
       clonedAnimalGroup.addAnimal(animal.clone);

    return clonedAnimalGroup;
}

Метод клонирования в Animal

protected Object clone() throws CloneNotSupportedException {
    Animal clonedAnimal = (Animal)super.clone();
    clonedAnimal.animalGroup = animalGroup.clone(); 
}

Это закончится циклом вызова AnimalGroup и наоборот.

Case2: copyConstructor

HashMap не поддерживает конструктор глубокого копирования

Предлагаемое решение

Я могу использовать конструктор для Animal внутри метода клонирования AnimalGroup следующим образом

Метод клонирования в AnimalGroup

protected Object clone() throws CloneNotSupportedException {
    AnimalGroup clonedAnimalGroup = (AnimalGroup)super.clone();
    for(Animal animal: animalList)
       clonedAnimalGroup.addAnimal(new Animal(animal, this));

    return clonedAnimalGroup;
}

Конструктор в Животном

public Animal(Animal other, AnimalGroup animalGroup)
{
  this.animalGroup = animalGroup;
  ...
}

Вопрос Есть ли лучшее решение для глубокого копирования в таком случае.

Изменить1

Размер данных слишком велик для подхода, связанного с сериализацией.

Изменить2

Я не могу включать внешние библиотеки и т. д. для копирования в свой проект.


person varsh    schedule 21.11.2013    source источник
comment
Тип дубликата: stackoverflow.com/questions/13049222/java-hashmap- глубокое копирование   -  person tilpner    schedule 21.11.2013
comment
Проблема в приведенном выше вопросе заключается не в том, как скопировать hashmap. Речь идет о том, как решить проблему рекурсивного обращения друг к другу двух классов в их методах клонирования.   -  person varsh    schedule 21.11.2013


Ответы (2)


Вы можете дать себе вспомогательные методы, необходимые для выполнения глубокого копирования. При глубоком копировании Animal вместо этого получите глубокую копию его группы и верните член этой группы, соответствующий копируемому Animal; при глубоком копировании группы получить новые копии членов, не назначая им какую-либо группу, добавить эти новые копии в новый список, назначить этот список в качестве группы для каждого элемента, а затем вернуть новый список. Для этого потребуется, чтобы у группы был доступ к специальному конструктору, который не назначает группу сразу.

Есть и другие подобные вариации на эту тему.

person Judge Mental    schedule 21.11.2013
comment
Это хороший ответ. Ваш ответ был бы идеальным для ситуации, когда Animal и AnimalGroup имели бы отношение один к одному, а не List‹Animal›. В любом случае, спасибо, я попробую это. Просто интересно, вы только сейчас придумали ответ или это как нормальная практика в таких ситуациях? - person varsh; 22.11.2013
comment
Должен работать даже в случае "один ко многим". Вам просто нужен deepCopyExceptGroup доступный в классе Animal. Я просто придумал это на лету, но этот тип алгоритма постоянно возникает с циклическими данными. Это напоминает мне кое-что, о чем я узнал на курсе языков программирования в бакалавриате. Я посмотрю, смогу ли я найти ссылку. - person Judge Mental; 22.11.2013
comment
Ссылка была бы кстати, спасибо. Между тем, я понимаю, что ваше решение будет хорошо и для «один ко многим», на самом деле я буду использовать аналогичный вариант, я просто указывал на случай «один на один». - person varsh; 22.11.2013

Вы можете сериализовать-десериализовать объект, который является надежным способом глубокого клонирования

person sanbhat    schedule 21.11.2013
comment
Конечно, есть эффективные способы сделать это с помощью сторонних маршаллеров/демаршаллеров. - person sanbhat; 21.11.2013