Реализация глубокой копии объекта Customer

Customer.clone должен создать новый Customer, новый Address, новый список и новые CellNumber внутри него. Одного super.clone либо копии списка недостаточно для глубокого клонирования.

Короткий ответ

Что ответить на собеседовании

Customer.clone должен создать новый Customer, новый Address, новый список и новые CellNumber внутри него. Одного super.clone либо копии списка недостаточно для глубокого клонирования.

Подробный разбор

Ответ с пояснениями

Условие

Задача состоит в том, чтобы реализовать метод clone() в классе Customer, который будет создавать полную (глубокую) копию данного объекта.

Требования:

  1. Склонированный объект не должен ссылаться на те же вложенные экземпляры (Address, List<CellNumber>), что и оригинал.
  2. Все вложенные структуры внутри Customer должны быть независимыми копиями.
  3. После выполнения клонирования метод equals() должен возвращать true, однако ссылки на вложенные объекты должны указывать на разные экземпляры.
package com.jetbulb.interviews;

import java.util.Collections;
import java.util.List;

public class JetbulbInterview {
    public static void main(String[] args) {
        Customer customer = new Customer(
                "123",
                66,
                new Address(1, "Street"),
                Collections.singletonList(new CellNumber("777-555-666", 3.14D))
        );

        Customer clonedCustomer = customer.clone();

        System.out.println(customer.equals(clonedCustomer)); // true
        System.out.println(customer == clonedCustomer); // false
        System.out.println(customer.address == clonedCustomer.address); // false
        System.out.println(customer.number == clonedCustomer.number); // false
    }
}

class Customer implements Cloneable {
    String id;
    int age;
    Address address;
    List<CellNumber> number;
}

class Address implements Cloneable {
    int id;
    String name;
}

class CellNumber implements Cloneable {
    String number;
    double coverage;
}

Ответ

Customer.clone должен создать новый Customer, новый Address, новый список и новые CellNumber внутри него. Одного super.clone либо копии списка недостаточно для глубокого клонирования.

При добавленных конструкторах из примера метод внутри Customer может выглядеть так:

@Override
public Customer clone() {
    Address copiedAddress = address == null ? null : new Address(address.id, address.name);
    List<CellNumber> copiedNumbers = null;
    if (number != null) {
        copiedNumbers = new java.util.ArrayList<>();
        for (CellNumber item : number)
            copiedNumbers.add(item == null ? null : new CellNumber(item.number, item.coverage));
    }
    return new Customer(id, age, copiedAddress, copiedNumbers);
}

В показанных объявлениях конструкторов и equals пока нет — их нужно добавить. Equals/hashCode у Customer сравнивают id, age, address, number; у Address и CellNumber — собственные поля, для double используют согласованные Double.compare/hashCode. Тогда значение копии равно оригиналу, но изменяемые вложения независимы. Строки копировать отдельно не нужно.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее