Customer.clone должен создать новый Customer, новый Address, новый список и новые CellNumber внутри него. Одного super.clone либо копии списка недостаточно для глубокого клонирования.
Реализация глубокой копии объекта Customer
Customer.clone должен создать новый Customer, новый Address, новый список и новые CellNumber внутри него. Одного super.clone либо копии списка недостаточно для глубокого клонирования.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Задача состоит в том, чтобы реализовать метод clone() в классе Customer, который будет создавать полную (глубокую) копию данного объекта.
Требования:
- Склонированный объект не должен ссылаться на те же вложенные экземпляры (
Address,List<CellNumber>), что и оригинал. - Все вложенные структуры внутри
Customerдолжны быть независимыми копиями. - После выполнения клонирования метод
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. Тогда значение копии равно оригиналу, но изменяемые вложения независимы. Строки копировать отдельно не нужно.