Создание объекта из существующего с помощью Lombok в Java
Быстрый ответ
Для того чтобы скопировать объект и изменить его свойства при помощи Lombok, используйте аннотацию @Builder(toBuilder = true), которая активизирует метод toBuilder():
@Builder(toBuilder = true)
public class Example {
    private String data;
    // Допустим, у нас есть также и другие поля
}
Example original = new Example("original");
Example clone = original.toBuilder().build();
Запомните:
- В вашем классе активизируйте @Builder(toBuilder = true);
- Для клонирования примените original.toBuilder();
- Создание объекта завершите с помощью метода .build().

Когда стоит использовать
toBuilder идеально подойдёт, когда важно сохранить неизменность или когда требуется создать новый экземпляр с целью изменить несколько свойств. Это гораздо удобнее, чем переприсваивать все поля вручную.
Эффективный
Если вам нужно внести изменения всего в одно или два поля, попробуйте @With. Он обеспечивает класс методами with для каждого поля, позволяя создать новый экземпляр без использования строителя:
@Data
@With
public class Example {
    private final String data;
    private final int count;
    // И т.д....
}
Example example = new Example("data", 42);
Example modified = example.withData("newData");
// Метод с @With, позволяющий изменить данные
Посмотрите на альтернативы
В дополнение к Lombok существуют и другие инструменты, например, ObjectMapper из Jackson для осуществления клонирования:
ObjectMapper mapper = new ObjectMapper();
Example source = new Example("source");
Example cloned = mapper.convertValue(source, Example.class);
// В результате получим практически идентичный клон
Учтите: для работы ObjectMapper требуется правильная настройка для игнорирования null и свойственных ему преобразований свойств.
Давайте обсудим вопрос производительности
@With более лёгок в использовании и подходит, когда требуется изменить лишь одно свойство. Но если предстоит внести много изменений, то лучше выбрать toBuilder().
Визуализация
Воспринимайте Lombok как игру в конструктор Lego. Вам предстоит построить что-то новое:
Исходный объект (🏠): [🚪 Дверь, 🪟 Окно, 🛁 Ванна]
После применения @Builder(toBuilder = true):
Новый объект (🏡): originalObject.toBuilder()
                                  .window(newWindow) // И вот у вас новое окно 🪟
                                  .build();
🏠 превратился в 🏡: [🚪 Дверь, 🆕🪟 Новое Окно, 🛁 Ванна]. Теперь у вас есть обновлённая конструкция с помощью удобного toBuilder от Lombok.
Цирк сложных объектов
В "джунглях" сложных объектов глубокое копирование может стать спасительным. В таких ситуациях toBuilder является всего лишь скромным инструментом, и стоит задуматься о глубоком клонировании для создания идеальных дубликатов.
Обработка наследования при помощи
Когда дело касается наследования, @SuperBuilder отлично справляется с задачей, выигрывая у toBuilder. Он помогает клонировать объекты с учётом иерархии классов, обеспечивая типизацию и соответствие стандарту строителя.
Шпаргалка по клонированию
- Используйте toBuilderдля массовых изменений и@Withдля единичных.
- Не создавайте излишнее количество экземпляров, чтобы снизить потребление памяти.
- Неизменяемые объекты изначально предусматривают возможность клонирования через их конструкторы.
- И помните: инкапсулируйте объект, чтобы предотвратить несанкционированные изменения.
Полезные материалы
- Stable – Всё, что вам нужно знать о Project Lombok.
- Понимание Builder и toBuilder в Lombok – Детальное руководство по использованию @BuilderиtoBuilder.
- Medium – Экспертные советы из Effective Java, Пункт 6: избегайте создания лишних объектов.
- Копирование свойств из одного объекта в другой с помощью BeanUtils – Мастерство работы со свойствами при помощи BeanUtils.
- Глубокое копирование в Java для создания объекта из другого – Разбор процесса реализации глубокого копирования.
- Oracle JavaDocs: Интерфейс Cloneable – Пояснения от Oracle по интерфейсу Cloneable.


