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

#java

#java

Вопрос:

для проекта, над которым я работаю, я хочу отредактировать arraylist с помощью моих пользовательских точечных объектов и передать его в рекурсивный метод, но только рекурсивный вызов имеет отредактированный arraylist. Поэтому я попытался отредактировать его заранее, передать копию, а затем изменить ее обратно, но поскольку она передается по ссылке, каждый из них изменяет другие значения. Как я могу сделать глубокую копию, чтобы я мог передать отредактированный массив, но сохранить оригинал нетронутым, а также разделить их? Я устанавливаю логические значения, которые я хотел бы сохранить при использовании нового метода, но на самом деле их нет в исходном массиве.

             for (Dot d : dots) {
                    if (d.isFull() amp;amp; d.left.isFull() amp;amp; !(d.left.left.isFull())) {
                        d.setEmpty();
                        d.left.setEmpty();
                        d.left.left.setFull();
                        ArrayList<Dot> newdots = new ArrayList<>(dots);
                        move(newdots);
                        d.setFull();
                        d.left.setFull();
                        d.left.left.setEmpty();
                    }
               
                    if (d.isFull() amp;amp; d.right.isFull() amp;amp; !(d.right.right.isFull())) {
                        d.setEmpty();
                        d.right.setEmpty();
                        d.right.right.setFull();
                        ArrayList<Dot> newdots = new ArrayList<>(dots);
                        move(newdots);
                        d.setFull();
                        d.right.setFull();
                        d.right.right.setEmpty();
                    }
 

Комментарии:

1. Вы пробовали клонировать объект перед редактированием объектов?

Ответ №1:

Если вы хотите глубоко клонировать объект в Java, у вас есть два способа:

  1. Используйте clone метод, но вы должны иметь в виду, что этот метод создает неглубокий клон. Если у вас есть объект, который содержит ссылки на другие объекты, будет клонирован только основной объект. Если вы хотите также клонировать дочерние элементы, вам нужно переопределить их метод clone, а в методе clone основного объекта вы должны их вызвать. Это должно быть сделано рекурсивно для всех внутренних объектов.
  2. Если ваш основной объект и все его дочерние Serializable элементы, то вы можете использовать следующий метод:
     <T extends Serializable> T deepClone(T t) throws IOException, ClassNotFoundException {
        return deserialize(serialize(t));
    }
    
    private <T extends Serializable> byte[] serialize(T t) throws IOException {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(t);
            return baos.toByteArray();
        }
    }
    
    private <T extends Serializable> T deserialize(byte[] data) throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
            return (T) ois.readObject();
        }
    }